[山东大学操作系统课程设计]实验六

0.写在前面:

事先说明一点,在实验六开始,绝大多数的问题我应该都无法解释了,因为我自己做这个实验都是有点困难的,所以在接下来我不会过多阐述原理上的东西,只交待这个东西是怎么做的。

另外实验六七又是连在一起的因此。。。。。唉,没办法,一起写了呗

1.实验需求分析:

实验需求大致可以去分为如下几个步骤:

1.在APPSpace中实现两个系统调用,第一关是print方法,另一个是Exec方法,这两个方法可以实现一个用户程序启动另一个用户程序,类似linux中fork这个东西

2.在用户程序中打印一个整数数值,也就是新增一个系统调用PrintInt

3.尝试说明,如何实现类似linux下的fork函数,还有及写时复写机制的实现:

2.实验具体操作步骤:

复制文件:

我们需要复制一下文件到lab6文件夹(关于这个文件夹还有一些需要处理的地方,这个我们会在第四个模块详细解释一下)

addrspace:

对于地址空间这个类(关于进程和地址空间的关系,这里我就不多解释了)

新增两个声明方法

在具体的类中,首先进行原有方法的修改:

AddrSpace::AddrSpace(OpenFile *executable)
{
    NoffHeader noffH;
    unsigned int i, size;

    bool flag = false;                        //将物理页面分配给进程使用
    for(i = 0; i < NumPhysPages; i++) {
        if(!ProgMap[i]) {
            ProgMap[i] = true;
            flag = true;                    //成功找到可分配的物理页面,即可完成分配
            spaceID = i;                 
            break;
        }
    }
    ASSERT(flag);                          //断言检查是否存在可用的物理页面
    //如果没有分配到,则进行输出返回

    executable->ReadAt((char *)&noffH, sizeof(noffH), 0);
    if ((noffH.noffMagic != NOFFMAGIC) && 
		(WordToHost(noffH.noffMagic) == NOFFMAGIC))
    	SwapHeader(&noffH);
    ASSERT(noffH.noffMagic == NOFFMAGIC);

// how big is address space?
    size = noffH.code.size + noffH.initData.size + noffH.uninitData.size 
			+ UserStackSize;	// we need to increase the size
						// to leave room for the stack
    numPages = divRoundUp(size, PageSize);
    size = numPages * PageSize;

    ASSERT(numPages <= NumPhysPages);		// check we're not trying
						// to run anything too big --
						// at least until we have
						// virtual memory

    DEBUG('a', "Initializing address space, num pages %d, size %d\n", 
					numPages, size);
// first, set up the translation 
    pageTable = new TranslationEntry[numPages];
    for (i = 0; i < numPages; i++) {
        pageTable[i].virtualPage = i;	// for TLB only
        pageTable[i].physicalPage = freeMM_Map->Find();
        pageTable[i].valid = TRUE;
        pageTable[i].use = FALSE;
        pageTable[i].dirty = FALSE;
        pageTable[i].readOnly = FALSE;  // if the code segment was entirely on 
					// a separate page, we could set its 
					// pages to be read-only
    }
    
// zero out the entire address space, to zero the unitialized data segment 
// and the stack segment
    bzero(machine->mainMemory, size);

// then, copy in the code and data segments into memory
    if (noffH.code.size > 0) {
        DEBUG('a', "Initializing code segment, at 0x%x, size %d\n", 
			noffH.code.virtualAddr, noffH.code.size);
    	unsigned int code_page = noffH.code.virtualAddr / PageSize; //寻找开始页面
    	unsigned int code_phy_addr = pageTable[code_page].physicalPage * PageSize;//使用页面和补偿计算物理地址
    	executable->ReadAt(&(machine->mainMemory[code_phy_addr]), noffH.code.size, noffH.code.inFileAddr);//获取存储
    }

    if (noffH.initData.size > 0) {
        DEBUG('a', "Initializing data segment, at 0x%x, size %d\n", 
			noffH.initData.virtualAddr, noffH.initData.size);
    	unsigned int data_page = noffH.initData.virtualAddr / PageSize;//寻找数据起点页面
    	unsigned int data_offset = noffH.initData.virtualAddr % PageSize;//第一个数据补偿的起点界面
    	unsigned int data_phy_addr = pageTable[data_page].physicalPage * PageSize + data_offset;  //和上一个分支中的代码一样
        executable->ReadAt(&(machine->mainMemory[data_phy_addr]), noffH.initData.size, noffH.initData.inFileAddr);//同上
    }

    Print();
}

//----------------------------------------------------------------------
// AddrSpace::~AddrSpace
// 	Dealloate an address space.
//----------------------------------------------------------------------

AddrSpace::~AddrSpace()
{
    ProgMap[spaceID] = 0;       //在解析构造方法中作出一定的修改
    for (unsigned int i = 0; i < numPages; i++)   //清理对应的内存
         freeMM_Map->Clear(pageTable[i].physicalPage);

    delete [] pageTable;
}

实现print方法,addrspace这个类就基本结束工作

void AddrSpace::Print(void)       //实现了print方法
{
	printf("spaceID: %u\n", spaceID);
    printf("Page table dump: %d pages in total\n", numPages);
    printf("============================================\n");
    printf("VirtPage, PhysPage\n");
    for (unsigned int i = 0; i < numPages; i++)
        printf("     %3d,      %3d\n", pageTable[i].virtualPage, pageTable[i].physicalPage);
    printf("============================================\n\n");
}

exception:

在这个类中,对唯一的方法进行重写

void
ExceptionHandler(ExceptionType which)       //该方法根据不同的异常情况完成重写
{
    int type = machine->ReadRegister(2);

    if (which == SyscallException) {
        switch (type) {	
            case SC_Halt:
                DEBUG('a', "Shutdown, initiated by user program.\n");
                interrupt->Halt();
                break;
            case SC_Exec:
                interrupt->Exec();
                machine->WriteRegister(PrevPCReg, machine->ReadRegister(PCReg));   //虽然调用不一样但是底下的逻辑是差不多的
	            machine->WriteRegister(PCReg, machine->ReadRegister(NextPCReg)); 
	            machine->WriteRegister(NextPCReg, machine->ReadRegister(NextPCReg) + 4); 
                break;
            
            default:
                printf("Syscall %d not implemented\n", type);
                machine->WriteRegister(PrevPCReg, machine->ReadRegister(PCReg)); 
	            machine->WriteRegister(PCReg, machine->ReadRegister(NextPCReg)); 
	            machine->WriteRegister(NextPCReg, machine->ReadRegister(NextPCReg) + 4); 
                break;
        }
    }
    else {
        printf("Unexpected user mode exception %d %d\n", which, type);
        ASSERT(FALSE);
    }
}

interrupt:

新增两个控制的方法:

在类中实现对于这两个方法的重构:

//执行一个用户进程

void Interrupt::Exec(void)
{
    printf("Execute system call of Exec()\n");

    // read argument
    char fileName[50];
    int addr = machine->ReadRegister(4);
    int i = 0;

    do {
       machine->ReadMem(addr + i, 1, (int*) &fileName[i]); // read filename from mainMemory
    } while(fileName[i++] != '\0');

    printf("Exec(%s):\n", fileName); 

    OpenFile *executable = fileSystem->Open(fileName);
    if (executable == NULL) {
        printf("Unable to open file %s to execute\n", fileName);
        return;
    }

    AddrSpace *space = new AddrSpace(executable);    
    delete executable;			// close execute file

    Thread *thread = new Thread(fileName);  // New thread for another user program
    thread->space = space;

    thread->Fork(RunProcess, (int)space->getSpaceID());
    currentThread->Yield();

    machine->WriteRegister(2, (int)space->getSpaceID());  // Return SpaceId
}


//打印并且获得一个整数

void Interrupt::PrintInt(int v)
{
    printf("%d\n", v);
}

system:

在宏定义也就是头文件中加入如下设定:

在cc文件中执行类似的操作即可

main:

最后将线程相关的宏定义修改为:

3.实验的测试工作:

编译以后按照指令进行调试

./nachos -x ../test/exec.noff

得到输出结果即为成功

4.遇到的问题:

好像没啥问题,哦对了注意一点

lab6这个文件名称最好不要改动,因为我发现不仅仅是local中用到了引用。。。

不过如果您头铁,当我另说

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/240944.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于“Python”的核心知识点整理大全17

目录 ​编辑 8.3.4 结合使用函数和 while 循环 greeter.py 8.4 传递列表 greet_users.py 8.4.1 在函数中修改列表 printing_models.py 8.4.2 禁止函数修改列表 要将列表的副本传递给函数&#xff0c;可以像下面这样做&#xff1a; 往期快速传送门&#x1f446;&#x…

java SSM教师工作量管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 教师工作量管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要…

【数学建模】《实战数学建模:例题与讲解》第十二讲-因子分析、判别分析(含Matlab代码)

【数学建模】《实战数学建模&#xff1a;例题与讲解》第十二讲-因子分析、判别分析&#xff08;含Matlab代码&#xff09; 基本概念时间判别费歇判别贝叶斯判别 习题10.31. 题目要求2.解题过程3.程序4.结果 习题10.6&#xff08;1&#xff09;1. 题目要求2.解题过程——对应分析…

OLED屏幕,如何成为商显主流

OLED屏幕在商显领域的应用逐渐增加&#xff0c;成为商显主流的原因主要有以下几点&#xff1a; 显示效果优异&#xff1a;OLED屏幕具有自发光原理&#xff0c;色彩鲜艳、对比度高、视角广&#xff0c;能够提供更好的视觉体验。在商业展示、广告宣传等场景中&#xff0c;OLED屏幕…

Feign-自定义配置

目录 一、自定义Feign配置 二、修改日志级别 方式一&#xff1a;application配置文件方式 方式二&#xff1a;java代码方式 三、总结 一、自定义Feign配置 二、修改日志级别 配置Feign日志有两种方式 方式一&#xff1a;application配置文件方式 &#xff08;1&#xff09…

Java服务占用过高CPU排查思路

一、背景说明 如果线上启动的Java服务占用过高的CPU&#xff0c;我们通过top命令是可以查看到的。 那么问题来了&#xff0c;如果通过top命令查看到是因为java服务引起的占用过高的CPU时间&#xff0c;该如何进行详细的排查呢&#xff1f;换句话说就是如何定位问题发生在代码的…

Vue中使用echarts@4.x中国地图及AMap相关API的使用

一、此 demo 实现的基本功能 1.中国地图的显示 2.地图点击下钻的功能 3.地图相关组件的使用&#xff0c;例 tooltip… 二、实现思路 初始使用下载本地的中国 geo 格式的 json 数据来绘制地图&#xff0c;点击某一区划&#xff08;例&#xff1a;山东省&#xff09;时&#xff0…

PySpark大数据处理详细教程

欢迎各位数据爱好者&#xff01;今天&#xff0c;我很高兴与您分享我的最新博客&#xff0c;专注于探索 PySpark DataFrame 的强大功能。无论您是刚入门的数据分析师&#xff0c;还是寻求深入了解大数据技术的专业人士&#xff0c;这里都有丰富的知识和实用的技巧等着您。让我们…

Centos7 配置Git

随笔记录 目录 1&#xff0c; 新建用户 2. 给用户设置密码相关操作 3. 为新用户添加sudo 权限 4. 配置Git 4.1 配置Git 4.2 查看id_ras.pub 5, 登录Git 配置SSH 秘钥 6. Centos7 登录Git 7. clone 指定branch到本地 8. 将新代码复制到指定路径 9. 上传指定代码 …

2023年11月国产数据库大事记-墨天轮

本文为墨天轮社区整理的2023年11月国产数据库大事件和重要产品发布消息。 11月国产数据库大事记 TOP10 11月国产数据库大事记&#xff08;时间线&#xff09; 11月1日消息&#xff0c;近日&#xff0c;由金仓数据库支撑的某大型运营商B域一级BOSS枢纽系统顺利升级上线。金仓数…

四川技能大赛——2023年四川网信人才技能大赛(网络安全管理员赛项)决赛

四川技能大赛——2023年四川网信人才技能大赛&#xff08;网络安全管理员赛项&#xff09;决赛 文章目录 四川技能大赛——2023年四川网信人才技能大赛&#xff08;网络安全管理员赛项&#xff09;决赛C1-比64少的bas - DONEC2-affine - DONEC3-简单的RSA - DONEM1-不要动我的f…

关于String.Format混合$符号格式化引发的问题

之前一个老项目是用string.Format()进行格式化的&#xff0c;.net 4.5之后的版本 引入 $"字符串" 格式化标识符&#xff0c; 如下代码&#xff1a; string barcode "1234567{#0.000}ABCDE";barcode "12345START{0:#000}ABCDE";try{string sFo…

【网络安全技术】电子邮件安全PGP,SMIME

一、PGP&#xff08;Pretty Good Privacy&#xff09; PGP是一种邮件加密手段&#xff0c;他在发邮件一方加密&#xff0c;然后发给发送方邮件服务器&#xff0c;发送方邮件服务器再发送给接收方邮件服务器&#xff0c;然后接收方再从接收方邮件服务器pop出来&#xff0c;这整…

vue实现自动打字效果(带光标效果)

代码介绍(其实就是通过字符串截取加定时拼接完成的,我相信有时间都能琢磨出来,来这里就是为了省事) 上vue页面代码: <template><div idApp><h2>{{text}}<span ref"fou" class"fousdis">{{_}}</span></h2></div>…

CentOS 7 部署frp穿透内网

本文将介绍如何在CentOS 7.9上部署frp&#xff0c;并通过示例展示如何配置和测试内网穿透。 文章目录 &#xff08;1&#xff09;引言&#xff08;2&#xff09;准备工作&#xff08;4&#xff09;frps服务器端配置&#xff08;5&#xff09;frpc客户端配置&#xff08;6&#…

工信部举行发布会 数字化产业推动元宇宙发展取得良好成效

据官方消息&#xff0c;工业和信息化部12日举行“发挥国家高新区作用 加快推进新型工业化”新闻发布会。 在数字化建设方面取得了良好的成绩&#xff1a; 一是数字经济加速发展。国家高新区着力推动人工智能、大数据、云计算、区块链和元宇宙等新产业新业态蓬勃发展&#xff…

1688订单详情接口使用指南:含代码实现获取订单信息

一、引言 随着电子商务的飞速发展&#xff0c;越来越多的企业开始通过1688平台进行采购和销售。为了更好地管理订单&#xff0c;提高客户满意度&#xff0c;许多企业选择使用1688订单详情接口来获取订单信息。本文将详细介绍如何使用1688订单详情接口&#xff0c;并提供示例代…

2023 年山东省职业院校技能大赛(高等职业教育) “信息安全管理与评估”样题

2023 年山东省职业院校技能大赛&#xff08;高等职业教育&#xff09; “信息安全管理与评估”样题 目录 任务 1 网络平台搭建&#xff08;50 分&#xff09; 任务 2 网络安全设备配置与防护&#xff08;250 分&#xff09; 模块二 网络安全事件响应、数字取证调查、应用程序安…

Guava的注解处理机制

第1章&#xff1a;引言 Guava不仅仅是一个工具库&#xff0c;它更像是Java程序员的瑞士军刀&#xff0c;提供了一系列强大的功能&#xff0c;从集合操作到函数式编程&#xff0c;再到今天咱们要深入探讨的——注解处理机制。 注解&#xff08;Annotations&#xff09;&#x…

14:00面试,14:08就出来了,问的问题有点变态。。。。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到5月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…