欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    Greekos操作系统实验.pdf

    • 资源ID:82064923       资源大小:1.02MB        全文页数:23页
    • 资源格式: PDF        下载积分:19.9金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要19.9金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Greekos操作系统实验.pdf

    Greekos 操作系统实验 2 作者:日期:个人收集整理 勿做商业用途 第 页 操作系统实验报告 目录 1。实验目的-2.开发环境的搭建-2.1 在虚拟机上安装 Linux-2。2 安装 VMware Tools 和实现文件共享-2。3 Bochs PC 模拟器的安装-3.项目具体实现-3.1 项目 0-3。1。1 项目设计要求-3.1。2 项目设计原理-3。1。3 项目设计的具体实现-3.1。4 系统编译运行的原理及结果-3.2 项目 1-3.2。1 项目设计要求-3.2。2 项目设计原理-3.2.3 项目设计的具体实现-3。2.4 系统编译运行的原理及结果-3.3 项目 2-3。3。1 项目设计要求-3。3。2 项目设计原理-3.3。3 项目设计的具体实现-3.3。4 系统编译运行的原理及结果-4.遇到的问题及解决办法-5。实验总结-个人收集整理 勿做商业用途 第 页 1.实验目的 操作系统是管理系统软件,硬件资源,控制程序运行,改善人机界面及交互,提供各种服务,合理组织计算机工作流程和为用户有效地使用计算机提供良好运行环境的系统软件,它为用户使用计算机提供了一个方便,灵活,安全,可靠的工作环境,它也是其他运用软件赖以存在的基础.操作系统是计算机科学与技术专业核心的课程,涉及到很多方面的知识,概念和原理抽象.在课程学习过程中,主要是学习理论知识,而操作系统实验则从理论转向实践,让我们亲自去编写一个操作系统内核,从而可以更加深入的理解操作系统软件的实现过程,增强了实践动手能力。本实验主要要求我们熟悉GeekOs的项目编译、调试和运行环境,掌握GeekOs运行工作过程。熟悉 ELF 文件格式,了解 GeekOs 系统如何将 ELF 格式的用户可执行程序装入到内存,建立内核线程并运行的实现技术。扩充 GeekOs 操作系统内核,使得系统能过支持用户级进程的动态创建和执行。2.开发环境的搭建 在实现这个过程中。由于 Geekos 是开源的基于 linux 系统开发的操作系统,我们需要用到linux下的编译环境。所以需要搭建linux环境。为了实现与Windows下的文件进行共享,需要安装VMware Tools 软件包。在运行的时候需要 bochs pc 模拟器来模拟操作系统,所以也需要安装 bochs pc 模拟器.2.1 在虚拟机上安装 Linux 本次环境的搭建是采用在 Windows 环境下先安装一个 PC 虚拟机,然后在虚拟机上安装Linux 操作系统。本次实验选择安装的虚拟机软件 VMware,安装过程则为首先在相应的网站下载此安装软 件,然 后 其 根 据 提 示 安 装。安 装 完 成 后 就 会 在 桌 面 上 显 示 一 个 虚 拟 机 图 标VMware-workstation。VMware 安装完成后,可以开始建立虚拟机,每新建一个虚拟机都会要求建立一个配置文件,这个配置文件相当于电脑中的硬件配置表,用户可以在配置文件中决定虚拟机的硬盘如何配置,内在多大,准备运行哪种操作系统,是否有网络等。其中中安装的过程中要选取实验需要的相应组件进行安装,其中本次实验必须需要的组件是:AWK、Diff3、Egrep、gcc、GNUbinutils、GNUMake、Perl、NASM。2.2 安装 VMware Tools 在虚拟机上安装 VMware Tools,就相当于给 Linux 安装各种驱动程序。此步的主要目的就是为了以后的工程运行时能够实现与Windows 下的文件进行共享,因为 bochs PC 模拟器要在 Windows 下运行,所以这里的文件就只能通过这一步的共享,从而达到在 Linux 下工程运行后得到的 build 下的镜像文件替代源文件,从而使得 bochs PC模拟器能够得到所需的镜像文件。2.3 安装 Bochs PC 模拟器 Bochs PC 模拟器:用来运行 GeekOS 系统.安装此软件只需设定好想安装到的文件目录后一直点下一步就可以安装成功。最后设置bochsrc。txt 文件。根据实验的需要,一般只需要修改以下几项:(1)vgaromimage:$BXSHARE/VGABIOS-lgpllatest(2)romimage:file=$BXSHARE/BIOSbochslatest,address=0 xf0000(3)floppya:1_44=fdx.img,status=inserted boot:floppy(4)做 Project 1 的时候,需要添加一个磁盘镜像 个人收集整理 勿做商业用途 第 页 ata0-master:type=disk,mode=flat,path=diskx。img,cylinders=615,heads=6,spt=17 配置完 bochsrc.txt 以后,而且有了从工程生成的操作系统 Geekos 就可以用 bochs软件模拟了。到 bochs 的安装目录下,输入 bochs 命令,选择 6 开始模拟。如果你的操作系统编译成功,就可以得到想要的结果。3.项目具体实现 3。1 项目 0 本项目主要目的是要熟悉GeekOS的项目编译、调试和运行环境,掌握GeekOS运行工作过程。3.1.1项目设计要求(1)搭建 GeekOS 的编译和调试平台,掌握 GeekOS 的内核进程工作原理。(2)熟悉键盘操作函数,编程实现一个内核进程.该进程的功能是:接收键盘输入的字符并显示到屏幕上,当输入 Ctrl+D 时,结、束进程的运行。3。1。2 项目设计原理 在这个项目里面主要了解两部分的内容:内核线程和键盘处理,相应的文件是 thread。c 和 keyboard.c。Geekos 系统的默认内核只支持内核态的线程,在系统初始化的时候,main 函数分别执行了 4 个内核函数,一个内核函数负责软驱中断,一个复杂键盘中断,还有两个负责进程调度。函数 Start_Kernel_Thread()其可以生成一个内核线程:1内核线程结构的定义如下:struct Kernel_Thread unsigned long esp;volatile unsigned long numTicks;int priority;DEFINE_LINK(Thread_Queue,Kernel_Thread);void*stackPage;struct User_Context*userContext;struct Kernel_Thread*owner;int refCount;Boolean alive;struct Mutex joinLock;struct Condition joinCond;;esp 字段用来存放一个线程挂起的堆栈指针;stackPage 字段指向内核线程的堆栈页面 numTicks 和 priority 分别被调度程序用来实现基于先占权和基于优先权的时间片调度。DEFINE_LINK 宏定义一个内核线程在线程队列上时的前一个和后一个字段。userContext 字段如果不为空,则指向一个线程用户环境,它是一个允许线程执行用户模式的代码和数据的组合段.内核线程有两种方式创建。在内核里独立运行的线程可通过 Start_Kernel_Thread()函数来创建,该函数通过一个指针指向一个执行线程体的启动函数。线程所执行的用户模式的程序由 Start_User_Thread()函数创建,并且用一指针指向一个用户环境和用户环境内存个人收集整理 勿做商业用途 第 页 中代码入口点的地址.调用 Exit()函数销毁内核线程。入口参数分别为:函数地址,函数参数(无参数就写 0),优先级设定,线程属性(false为内核线程,true 为用户线程),返回值 Mythread 的数据类型是 static struct Kernel_Thread*thread 2Start_Kernel_Thread 完成的工作:Create_Thread(priority,detached)/根据优先级创建一条线程 kthread=Alloc_Page()/为线程分配内存空间 stackPage=Alloc_Page()Init_Thread(kthread,stackPage,priority,detached)Add_To_Back_Of_All_Thread_List(s_allThreadList,kthread)Setup_Kernel_Thread(kthread,startFunc,arg)/配置内核线程的初始化 Make_Runnable_Atomic(kthread);/设置线程运行的原子性操作 Disable_Interrupts();/禁止中断 Make_Runnable(kthread);/线程运行 Enable_Interrupts();/使能中断 3Geekos 处理键盘代码 在 keyboard.c 里面提供了一个功用函数 Keycode Wait_For_Key(void),循环等待一个键盘事件,然后返回一个 16 位的数据 Keycode 型的,在keyboard.h 里定义了所有的键盘代码.Read_Key(Keycode keycode)函数可以处理队列键盘按键,可以保存到队列中并输出。关于 Keycode 的定义是:低 8 位用来表示键盘值,通过 s_scanTableNoShift 和s_scanTableWithShift这两个数组来转换相应的键盘码为所表示字符的ASCII码,高六位分别是:KEY_SPECIAL_FLAG(特殊键,比如 F1,F2)用返回的值 key0 x0100 就可以判断是否按下特殊健,1 为有效,说明是特殊健,0 则不是,以下的几种情况类似 KEY_KEYPAD_FLAG (小键盘键)0 x0200 KEY_SHIFT_FLAG (左,右 SHIFT)0 x1000 KEY_ALT_FLAG (左,右 ALT)0 x2000 KEY_CTRL_FLAG (左,右 CTRL)0 x4000 KEY_RELEASE_FLAG (键弹起来标志位)0 x8000 3.1.3 项目设计的具体实现 projcet0 项目主要是对 main.c 文件中的键盘相应的实现。我们创建函数keyboard()。下面是具体的代码.void keyboard(ulong_t arg)Keycode key;Print(”Please Enter the characters.press Ctrl+d to exitnn);while(true)Set_Current_Attr(ATTRIB(BLACK,REDBRIGHT));key=Wait_For_Key();if(key=(KEY_CTRL_FLAG+d))Print(nnKey Endn);个人收集整理 勿做商业用途 第 页 break;if(!(keyKEY_RELEASE_FLAG)&!(key&KEY_SPECIAL_FLAG))Print(c,key);void Main(struct Boot_Info bootInfo)Init_BSS();Init_Screen();Init_Mem(bootInfo);Init_CRC32();Init_TSS();Init_Interrupts();Init_Scheduler();Init_Traps();Init_Timer();Init_Keyboard();Set_Current_Attr(ATTRIB(BLACK,GREEN|BRIGHT);Print(nnWelcome to sutingtings GeekOS!nn”);Start_Kernel_Thread(keyboard,0,5,1);Set_Current_Attr(ATTRIB(BLACK,GRAY));TODO(”Start a kernel thread to echo pressed keys and print counts”);Exit(0);3。1。4 系统编译运行的原理及结果 I编译源代码 在 linux 的终端中:(1)输入:cd+空格+路径(project0 文件下的 build 文件所在的路径)(2)终端进入 build 目录$make depend make 如果没有问题就会自动生成一个镜像文件 fd.img。II 修改 bochsrc。txt 配置文件 其具体的文件 bochsrc。txt 内容如下:配置模拟器的 BIOS 和显示系统的 BIOS 文件 vgaromimage:$BXSHARE/VGABIOSlgpllatest romimage:file=BXSHARE/BIOSbochslatest,address=0 xf0000 配置模拟器内存大小 megs:8 个人收集整理 勿做商业用途 第 页#配置模拟器从软盘引导系统 boot:a#这是对模拟器硬盘的描述,其中 disk。img 是硬盘的映像文件,将其注释掉,因为项目 0#不需要硬盘。#软盘 A 的描述,其中 fd.img 为软盘映像文件 floppya:1_44=fd.img,status=inserted floppya:1_44=fd_aug。img,status=inserted#这是配置模拟器的系统文件 keyboard_serial_delay:200 floppy_command_delay:500 vga_update_interval:300000 ips:1000000 mouse:enabled=0 private_colormap:enabled=0 i440fxsupport:enabled=0 配置模拟器的日志文件 log:。/bochs。out III。运行 bochs 终端运行 bochs 选择 6 即的运行结果如下图 1 所示:图 1 project0 的运行结果 3.2 项目 1 本项目主要是为了让学生熟悉ELF文件格式,了解Geekos系统如何将 ELF 格式的用户可执行程式装入到内存,建立内核进程并运行的实现技术.3。2.1 项目设计要求 分析 ELF 格式的可执行文件(包括分析得出 ELF 文件头、程序头,获取可执行文件的长度,代码段、数据段等信息),并填充 Exe_Format 数据结构中的域值.个人收集整理 勿做商业用途 第 页(1)修改/geekos/elf.c 文件:在函数 Parse_ELF_Executable()中添加代码,分析 ELF格式的可执行文件(包括分析得出 ELF 文件头、程序头,获取可执行文件长度,代码段、数据段等信息),并填充 Exe_Format 数据结构中的域值。(2)在 Linux 环境下编译系统得到 GeekOS 镜像文件。(3)编写一个相应的 bochs 配置文件。(4)在 bochs 中运行 GeekOS 系统显示结果。3.2。2 项目设计原理 项目的主要内容是在文件 elf.c 中 函数 Parse_ELF_Executable()添加代码,实现对 ELF 文件的解释,装入到内存运行,得到指定的结果.主要是分析ELF文件。为以后的工程执行应用程序做准备,需要理解的是 ELF的一下原理性.需要关注以下几个数据结构:具体代码在project1 includegeekoself.h 中:typedef struct unsigned char ident16;unsigned short type;unsigned short machine;unsigned int version;unsigned int entry;unsigned int phoff;/program header 偏移量 unsigned int sphoff;/section header 的 偏移 unsigned int flags;/指示具体的进程 unsigned short ehsize;/elf 头部的大小 unsigned short phentsize;/program header 的大小 unsigned short phnum;/program header 的个数 unsigned short shentsize;unsigned short shnum;unsigned short shstrndx;elfHeader;struct Exe_Format struct Exe_Segment segmentListEXE_MAX_SEGMENTS;/段的定义 int numSegments;/可执行文件中段的个数 ulong_t entryAddr;/代码入口;struct Exe_Segment ulong_t offsetInFile;/段在可执行文件中的偏移 ulong_t lengthInFile;/段在可执行文件中的长度 ulong_t startAddress;/段在内存中的起始地址 ulong_t sizeInMemory;/段在内存中的大小 int protFlags;/VM 保护标志;typedef struct 个人收集整理 勿做商业用途 第 页 unsigned int type;unsigned int offset;unsigned int vaddr;unsigned int paddr;unsigned int fileSize;unsigned int memSize;unsigned int flags;unsigned int alignment;programHeader;offset 表示该成员给出了该段的驻留位置相对于文件开始处的偏移。fileSize 表示该成员给出了文件映像中该段的字节数;它可能是 0.memSize 表示该成员给出了内存映像中该段的字节数;它可能是 0。vaddr 表示该成员给出了该段在内存中的首字节地址。flags 表示该成员给出了和该段相关的标志。这是编程实现过程主要部分,对 linux 下 ELF 有一定了解之后,就能顺利的完成工程 1。3。2。3 项目设计的具体实现 下面是 project1srcgeekos 下的 elf。c 中的代码。include geekos/errno。h#include include geekos/ktypes。h include /for debug Print()statements/#include#include geekos/malloc。h#include geekos/string。h include phoff);Set_Current_Attr(ATTRIB(BLACK,BLUE|BRIGHT));Print(ident=%s,”,headident);Print(”type=%d,headtype);Print(”machine=%d,”,headmachine);Print(”version=%d n,headversion);Print(”entry=d,head-entry);Print(”phoff=d,headphoff);Print(”sphoff=%d,,head-sphoff);Print(”flags=%dn,headflags);Print(ehsize=d,”,headehsize);Print(phentsize=%d,head-phentsize);Print(”phnum=%d,head-phnum);个人收集整理 勿做商业用途 第 页 Print(shentsize=%dn,head-shentsize);Print(”shnum=%d,,headshnum);Print(shstrndx=dn,headshstrndx);Set_Current_Attr(ATTRIB(BLACK,RED|BRIGHT);Print(”type=%d,,proHeadertype);Print(”offset=d,proHeader-offset);Print(vaddr=%d,proHeadervaddr);Print(”paddr=dn”,proHeaderpaddr);Print(”fileSize=%d,”,proHeaderfileSize);Print(memSize=d,proHeader-memSize);Print(flags=d,proHeaderflags);Print(”alignment=dn”,proHeader-alignment);Set_Current_Attr(ATTRIB(BLACK,GREEN|BRIGHT);for(i=0;isegmentListi。offsetInFile=proHeader-offset;exeFormatsegmentListi。lengthInFile=proHeaderfileSize;exeFormat-segmentListi.startAddress=proHeadervaddr;exeFormatsegmentListi。sizeInMemory=proHeader-memSize;exeFormat-segmentListi.protFlags=proHeaderflags;proHeader+;exeFormat-numSegments=head-phnum;exeFormat-entryAddr=head-entry;return 0;3.2。4 系统编译运行的原理及结果 I编译源代码 在 linux 的终端中:(1)输入:cd+空格+路径(project1 文件下的 build 文件所在的路径)(2)终端进入 build 目录$make depend$make 如果没有问题就会自动生成两个镜像文件 fd.img 和 diskc。img。II 修改。bochsrc.txt 配置文件 其具体的文件 bochsrc。txt 内容如下:vgaromimage:$BXSHARE/VGABIOSlgpllatest romimage:file=BXSHARE/BIOSbochs-latest,address=0 xf0000 megs:8 boot:a#diskc:file=diskc.img,cyl=40,heads=8,spt=64 个人收集整理 勿做商业用途 第 页 这是对模拟器硬盘的描述,其中disk.img是硬盘的映像文件.ata0:enabled=1,ioaddr1=0 x1f0,ioaddr2=0 x3f0,irq=14 ata0-master:type=disk,mode=flat,path=diskc.img,cylinders=40,heads=8,spt=64 floppya:1_44=fd。img,status=inserted floppya:1_44=fd_aug。img,status=inserted keyboard_serial_delay:200 floppy_command_delay:500 vga_update_interval:300000 ips:1000000 mouse:enabled=0 private_colormap:enabled=0 i440fxsupport:enabled=0 log:。/bochs.out III.运行 bochs 终端运行 bochs 选择 6 即的运行结果如下图 2 所示:图 2 project1 的运行结果 3.3 项目 2 本项目主要的任务是扩展 Geekos 操作系统内核,使得系统能够支持用户级进程的动态创建和执行。3。3.1项目设计要求(1)修改 user.c 中的函数 Spawn(),其功能是生成一个新的用户级进程.(2)修改 user。c 中函数 Switch_To_UserContext(),调度程序在执行一个新的进程前调用该函数以切换用户地址空间。(3)修改文件 elf.c 文件中的函数 Parse_ELF_Executable().这个在项目一已经实现。个人收集整理 勿做商业用途 第 页(4)修改 userseg。c 文件中的 Destroy_User_Context()、Load_User_Program()、Copy_From_User()、Copy_To_User()和 Switch_To_Address_Space()。(5)修改 kthread.c 文件中的 Start_User_Thread()和 Setup_User_Thread()函数(6)实现 kthread。c 中的一些系统调用函数定义。要求用户实现的有 Sys_Exit()函数、Sys_PrintString()函数、Sys_GetKey()、Sys_SetAttr()、Sys_GetCursor()、Sys_PutCursor()、Sys_Spawn()函数、Sys_Wait()函数和 Sys_GetPID()函数。(7)在 main.c 文件中改写生成第一个用户态进程的函数调用:Spawn_Init_Process(void).3.3。2 项目设计原理 项目需要实现用户进程,其实用户进程就是基于内核进程的一个改进。内核进程控制块结构 Kernel_Thread 中有一个字段 User_Context,而在初始化内核进程的函数时系统将其初始化为零;User_Context 字段其实就是上下文数据结构,定义如下:Struct User_Context#define NUM_USER_LDT_ENTRIES 3 Struct Segment_Descriptor ldtNUM_USRE_LDT_ENTRIES;Struct segment_Descriptor*ldtDsecriptor;Char*memory;Ulong_t size;Ushort_t ldtSelector;Ushort_t csSelector;Ushort_t dsSelector;Pde_t pageDir;Ulong_t entryAddr;Ulong_t argBlockAddr;Ulong_t stackPointerAddr;Int refCount;#if 0 Int semaphores#endif;Struct Segment Descriptor ldtNUM_USER_LDT_ENTRIES:是 Segment Descriptor数组,这里只有两个元素,一个 Segment 用于用户进程的数据,一个 Segment 用于用户进程的代码。ldtDescriptor 是 LDT 的描述 Segment Descriptor,memory 是用户内存空间的其实地址。Size 是用户空间的大小.entryAddr 是用户代码的其实地址,进程就是从这个地址开始运行的。3。3.3 项目设计的具体实现 主要修改以下文件中的函数:User.c 中 int Spawn(const char program,const char*command,struct Kernel_Thread*pThread)个人收集整理 勿做商业用途 第 页 int rc;char exeFileData=0;ulong_t exeFileLength;struct User_Context userContext=0;struct Kernel_Thread process=0;struct Exe_Format exeFormat;if(rc=Read_Fully(program,(void)&exeFileData,&exeFileLength))!=0|(rc=Parse_ELF_Executable(exeFileData,exeFileLength,&exeFormat))!=0|(rc=Load_User_Program(exeFileData,exeFileLength,&exeFormat,command,userContext))!=0)goto fail;Free(exeFileData);exeFileData=0;/开始用户进程/process=Start_User_Thread(userContext,false);if(process!=0)KASSERT(process-refCount=2);/返回核心进程的指针*/pThread=process;else rc=ENOMEM;return rc;fail:if(exeFileData!=0)Free(exeFileData);if(userContext!=0)Destroy_User_Context(userContext);return rc;void Switch_To_User_Context(struct Kernel_Thread*kthread,struct Interrupt_State*state)static struct User_Context*s_currentUserContext;/*last user context used*/extern int userDebug;struct User_Context*userContext=kthread-userContext;KASSERT(!Interrupts_Enabled());if(userContext=0)/核心态进程,无需改变地址空间。/return;if(userContext!=s_currentUserContext)个人收集整理 勿做商业用途 第 页 ulong_t esp0;if(userDebug)Print(A%pn”,kthread);Switch_To_Address_Space(userContext);esp0=((ulong_t)kthread-stackPage)+PAGE_SIZE;if(userDebug)Print(Slxn,esp0);/*新进程的核心栈./Set_Kernel_Stack_Pointer(esp0);/*New user context is active/s_currentUserContext=userContext;Elf.c 中 int Parse_ELF_Executable(char*exeFileData,ulong_t exeFileLength,struct Exe_Format exeFormat)int i;elfHeader*head=(elfHeader)exeFileData;programHeader proHeader=(programHeader)(exeFileData+head-phoff);KASSERT(exeFileData!=NULL);KASSERT(exeFileLengthhead-ehsize+headphentsize*headphnum);KASSERT(headentry4=0);exeFormat-numSegments=head-phnum;exeFormatentryAddr=headentry;for(i=0;ihead-phnum;i+)exeFormat-segmentListi。offsetInFile=proHeaderoffset;exeFormatsegmentListi.lengthInFile=proHeaderfileSize;exeFormat-segmentListi。startAddress=proHeader-vaddr;exeFormat-segmentListi.sizeInMemory=proHeader-memSize;exeFormat-segmentListi。protFlags=proHeader-flags;proHeader+;return 0;Userseg.c 中 void Destroy_User_Context(struct User_Context*userContext)Free_Segment_Descriptor(userContext-ldtDescriptor);userContext-ldtDescriptor=0;/释放内存空间 Free(userContextmemory);个人收集整理 勿做商业用途 第 页 userContext-memory=0;/释放userContext本身占用的内存 Free(userContext);userContext=0;int Load_User_Program(char exeFileData,ulong_t exeFileLength,struct Exe_Format exeFormat,const char*command,struct User_Context pUserContext)int i;ulong_t maxva=0;/要分配的最大内存空间 unsigned numArgs;/进程数目 ulong_t argBlockSize;/参数块的大小 ulong_t size,argBlockAddr;/参数块地址 struct User_Context userContext=0;/计算用户态进程所需的最大内存空间 for(i=0;i exeFormat-numSegments;+i)/elf.h struct Exe_Segment segment=&exeFormat-segmentListi;ulong_t topva=segmentstartAddress+segment-sizeInMemory;/*FIXME:range check/if(topva maxva)maxva=topva;Get_Argument_Block_Size(command,numArgs,&argBlockSize);/获取参数块信息 size=Round_Up_To_Page(maxva)+DEFAULT_USER_STACK_SIZE;/用户进程大小=参数块总大小+进程堆栈大小(8192)argBlockAddr=size;size+=argBlockSize;userContext=Create_User_Context(size);/按相应大小创建一个进程 if(userContext=0)/如果为核心态进程 return 1;for(i=0;i segmentListi;/根据段信息将用户程序中的各段内容复制到分配的用户内存空间 memcpy(userContext-memory+segment-startAddress,exeFileData+segmentoffsetInFile,segmentlengthInFile);/格式化参数块 Format_Argument_Block(userContext-memory+argBlockAddr,numArgs,argBlockAddr,command);/初始化数据段,堆栈段及代码段信息 userContext-entryAddr=exeFormatentryAddr;userContext-argBlockAddr=argBlockAddr;userContextstackPointerAddr=argBlockAddr;/将初始化完毕的User_Context赋给*pUserContext *pUserContext=userContext;return 0;/成功 bool Copy_From_User(void*destInKernel,ulong_t srcInUser,ulong_t bufSize)struct User_Context*current=g_currentThreaduserContext;if(!Validate_User_Memory(current,srcInUser,bufSize))return false;memcpy(destInKernel,User_To_Kernel(current,srcInUser),bufSize);return true;

    注意事项

    本文(Greekos操作系统实验.pdf)为本站会员(l***)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开