ImageVerifierCode 换一换
格式:DOCX , 页数:17 ,大小:134.54KB ,
资源ID:19136656      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/19136656.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(计算机操作系统实验运行用户态程序Word格式.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

计算机操作系统实验运行用户态程序Word格式.docx

1、Failed to Parse ELF File! if(rc = Load_User_Program(exeFileData, exeFileLength, &exeFormat, command, &userContext) != 0)Failed to Load User Program! /在堆分配方式下释放内存并再次初始化exeFileData Free(exeFileData); exeFileData = 0; /* 开始用户进程,调用Start_User_Thread函数创建一个进程并使其进入准备运行队列*/ process = Start_User_Thread(userCo

2、ntext, false); if (process != 0) KASSERT(process-refCount = 2); /* 返回核心进程的指针 */ *pThread = process; rc = process-pid;/记录当前进程的ID else rc = ENOMEM; return rc; fail: /如果新进程创建失败则注销User_Context对象 if (exeFileData ! Free(exeFileData);/释放内存 if (userContext ! Destroy_User_Context(userContext);/销毁进程对象 return

3、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 (user

4、Context = 0) /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(S%lxn, esp0); /* 新进程的核心栈.

5、 */ 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=(progra

6、mHeader *)(exeFileData+head-phoff); KASSERT(exeFileData!=NULL); KASSERT(exeFileLengthhead-ehsize+head-phentsize*head-phnum); KASSERT(head-entry%4=0); exeFormat-numSegments=head-phnum;entryAddr=head-entry; for(i=0;isegmentListi.offsetInFile=proHeader-offset;segmentListi.lengthInFile=proHeader-fileSiz

7、e;segmentListi.startAddress=proHeader-vaddr;segmentListi.sizeInMemory=proHeader-memSize;segmentListi.protFlags=proHeader-flags; proHeader+; return 0;= userseg.c =/需在此文件各函数前增加一个函数,此函数的功能是按给定的大小创建一个用户级进程上下文,具体实现如下:/函数功能:按给定的大小创建一个用户级进程上下文static struct User_Context* Create_User_Context(ulong_t size) st

8、ruct User_Context * UserContext; size = Round_Up_To_Page(size); UserContext = (struct User_Context *)Malloc(sizeof(struct User_Context); if (UserContext ! UserContext-memory = Malloc(size); /为核心态进程 goto fail; /内存为空 if (0 = UserContext-memory) memset(UserContext-memory, 0, size);size = size; /以下为用户态进

9、程创建LDT(段描述符表) /新建一个LDT描述符ldtDescriptor = Allocate_Segment_Descriptor();ldtDescriptor) /初始化段描述符 Init_LDT_Descriptor(UserContext-ldtDescriptor, UserContext-ldt, NUM_USER_LDT_ENTRIES); /新建一个LDT选择子ldtSelector = Selector(KERNEL_PRIVILEGE, true, Get_Descriptor_Index(UserContext-ldtDescriptor); /新建一个文本段描述符

10、 Init_Code_Segment_Descriptor( &UserContext-ldt0, (ulong_t) UserContext-memory, size / PAGE_SIZE, USER_PRIVILEGE ); /新建一个数据段 Init_Data_Segment_Descriptor(ldt1, /新建数据段和文本段选择子csSelector = Selector(USER_PRIVILEGE, false, 0);dsSelector = Selector(USER_PRIVILEGE, false, 1); /将引用数清0refCount = 0; return Us

11、erContext;fail:= 0) if (UserContext-memory ! Free(UserContext-memory); Free(UserContext);-/摧毁用户上下文void Destroy_User_Context(struct User_Context* userContext)Destroy a User_Context /释放占用的LDT Free_Segment_Descriptor(userContext-ldtDescriptor); userContext-ldtDescriptor=0; /释放内存空间 Free(userContext-memo

12、ry=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)Load a user executable into a user memory space using segmentation ulong_t maxva = 0;/要分配的最大内

13、存空间 unsigned numArgs;/进程数目 ulong_t argBlockSize;/参数块的大小 ulong_t size, argBlockAddr;/参数块地址 /计算用户态进程所需的最大内存空间 for (i = 0; i segmentListi; ulong_t topva = segment-startAddress + segment-sizeInMemory; /* FIXME: range check */ if (topva maxva) maxva = topva; Get_Argument_Block_Size(command, &numArgs, &ar

14、gBlockSize);/获取参数块信息 size = Round_Up_To_Page(maxva) + DEFAULT_USER_STACK_SIZE; argBlockAddr = size; size += argBlockSize; userContext = Create_User_Context(size);/按相应大小创建一个进程 if (userContext = 0)/如果为核心态进程 return -1; struct Exe_Segment *segment = & /根据段信息将用户程序中的各段内容复制到分配的用户内存空间 memcpy(userContext-mem

15、ory + segment-startAddress, exeFileData + segment-offsetInFile,segment-lengthInFile); /格式化参数块 Format_Argument_Block(userContext-memory + argBlockAddr, numArgs, argBlockAddr, command); /初始化数据段,堆栈段及代码段信息entryAddr = exeFormat-entryAddr;argBlockAddr = argBlockAddr;stackPointerAddr = argBlockAddr; /将初始化完

16、毕的User_Context赋给*pUserContext *pUserContext = userContext;/成功/将用户态的进程复制到内核缓冲区bool Copy_From_User(void* destInKernel, ulong_t srcInUser, ulong_t bufSize) struct User_Context * UserContext = g_currentThread- /-: check if memory if validated if (!Validate_User_Memory(UserContext,srcInUser, bufSize) ret

17、urn false; memcpy(destInKernel, UserContext-memory + srcInUser, bufSize); return true;-/将内核态的进程复制到用户态bool Copy_To_User(ulong_t destInUser, void* srcInKernel, ulong_t bufSize)Validate_User_Memory(UserContext, destInUser, bufSize) memcpy(UserContext-memory + destInUser, srcInKernel, bufSize);-/切换到用户地址

18、空间void Switch_To_Address_Space(struct User_Context *userContext) ushort_t ldtSelector= userContext-ldtSelector;/* Switch to the LDT of the new user context */ _asm_ _volatile_ (lldt %0:a(ldtSelector);= kthread.c =添加头文件 #include -/创建一个用户进程/*static*/ void Setup_User_Thread(struct Kernel_Thread* kthrea

19、d, struct User_Context* userContext) ulong_t eflags = EFLAGS_IF; unsigned csSelector=userContext-csSelector;/CS选择子 unsigned dsSelector=userContext-dsSelector;/DS选择子 Attach_User_Context(kthread, userContext); /初始化用户态进程堆栈,使之看上去像刚被中断运行一样 /分别调用Push函数将以下数据压入堆栈 Push(kthread, dsSelector); /数据选择子 Push(kthre

20、ad, userContext-stackPointerAddr); /堆栈指针 Push(kthread, eflags); /Eflags Push(kthread, csSelector); /文本选择子entryAddr); /程序计数器 Push(kthread, 0); /错误代码(0) /中断号(0) /初始化通用寄存单元,将ESI用户传递参数块地址 /* eax */ /* ebx */ /* edx */argBlockAddr); /* esi */ /* edi */ /* ebp */ /初始化数据段寄存单元 /* ds */ /* es */ /* fs */ /*

21、gs */开始用户进程struct Kernel_Thread* Start_User_Thread(struct User_Context* userContext, bool detached) struct Kernel_Thread* kthread = Create_Thread(PRIORITY_USER, detached); if (kthread ! Setup_User_Thread(kthread, userContext); Make_Runnable_Atomic(kthread); return kthread;= syscall.c =/需在此文件别的函数前增加一

22、个函数,函数名为Copy_User_String,它被函数Sys_PrintString调用,具体实现如下:static int Copy_User_String(ulong_t uaddr, ulong_t len, ulong_t maxLen, char *pStr) int rc = 0; char *str; if (len maxLen) /超过最大长度 return EINVALID; str = (char*) Malloc(len+1); /为字符串分配空间 if (0 = str) rc = ENOMEM;Copy_From_User(str, uaddr, len) /从用户空间中复制数据 rc = EINVALID; Free(str); strlen = ; /成功 *pStr = str;static int Sys_Exit(struct Interrupt_State* st

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1