好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

计算机操作系统实验-运行用户态程序.doc

13页
  • 卖家[上传人]:cn****1
  • 文档编号:398703204
  • 上传时间:2023-11-11
  • 文档格式:DOC
  • 文档大小:210KB
  • / 13 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 西北工业大学 操作系统实验 实验报告一、实验目的掌握在GeekOS系统用户态模式下加载并运行可执行程序的方法二、实验要求1. 按照实验讲义P127页中的设计要求,实现在用户态模式下加载并运行可执行程序的代码,给出关键函数的代码以及实验结果三、实验过程及结果答:核心函数代码如下:================== user.c ===============//产生一个进程(用户态)int Spawn(const char *program, const char *command, struct Kernel_Thread **pThread){ //TODO("Spawn a process by reading an executable from a filesystem"); 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 ) { Print("Failed to Read File %s!\n", program); goto fail; } if((rc = Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat)) != 0 ) { Print("Failed to Parse ELF File!\n"); goto fail; } if((rc = Load_User_Program(exeFileData, exeFileLength, &exeFormat, command, &userContext)) != 0) { Print("Failed to Load User Program!\n"); goto fail; } //在堆分配方式下释放内存并再次初始化exeFileData Free(exeFileData); exeFileData = 0; /* 开始用户进程,调用Start_User_Thread函数创建一个进程并使其进入准备运行队列*/ process = Start_User_Thread(userContext, false); if (process != 0) { KASSERT(process->refCount == 2); /* 返回核心进程的指针 */ *pThread = process; rc = process->pid;//记录当前进程的ID } else rc = ENOMEM; return rc; fail: //如果新进程创建失败则注销User_Context对象 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) { //userContext为0表示此进程为核心态进程就不用切换地址空间 return; } if (userContext != s_currentUserContext) { ulong_t esp0; //if (userDebug) Print("A[%p]\n", kthread); Switch_To_Address_Space(userContext);//为用户态进程时则切换地址空间 esp0 = ((ulong_t) kthread->stackPage) + PAGE_SIZE; //if (userDebug) // Print("S[%lx]\n", 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(exeFileLength>head->ehsize+head->phentsize*head->phnum); KASSERT(head->entry%4==0); exeFormat->numSegments=head->phnum; exeFormat->entryAddr=head->entry; for(i=0;iphnum;i++) { exeFormat->segmentList[i].offsetInFile=proHeader->offset; exeFormat->segmentList[i].lengthInFile=proHeader->fileSize; exeFormat->segmentList[i].startAddress=proHeader->vaddr; exeFormat->segmentList[i].sizeInMemory=proHeader->memSize; exeFormat->segmentList[i].protFlags=proHeader->flags; proHeader++; } return 0;}=================== userseg.c ===================//需在此文件各函数前增加一个函数,此函数的功能是按给定的大小创建一个用户级进程上下文,具体实现如下://函数功能:按给定的大小创建一个用户级进程上下文static struct User_Context* Create_User_Context(ulong_t size){ struct User_Context * UserContext; size = Round_Up_To_Page(size); UserContext = (struct User_Context *)Malloc(sizeof(struct User_Context)); if (UserContext != 0) UserContext->memory = Malloc(size); //为核心态进程 else goto fail; //内存为空 if (0 == UserContext->memory) goto fail; memset(UserContext->memory, '\0', size); UserContext->size = size; //以下为用户态进程创建LDT(段描述符表) //新建一个LDT描述符 UserContext->ldtDescriptor = Allocate_Segment_Descriptor(); if (0 == UserContext->ldtDescriptor) goto fail; //初始化段描述符 Init_LDT_Descriptor(UserContext->ldtDescriptor, UserContext->ldt, NUM_USER_LDT_ENTRIES); //新建一个LDT选择子 UserContext->ldtSelector = Selector(KERNEL_PRIVILEGE, true, Get_Descriptor_Index(UserContext->ldtDescriptor)); //新建一个文本段描述符 Init_Code_Segment_Descriptor( &UserContext->ldt[0], (ulong_t) UserContext->memory, size / PAGE_SIZE, USER_PRIVILEGE ); //新建一个数据段 Init_Data_Segment_Descriptor( &UserContext->ldt[1], (ulong_t) UserContext->memory, size / PAGE_SIZE, USER_PRIVILEGE ); //新建数据段和文本段选择子 UserContext->csSelector = Selector(USER_PRIVILEGE, false, 0); UserContext->dsSelector = Selector(USER_PRIVILEGE, false, 1); //将引用数清0 UserContext->refCount = 0; return UserContext;fail: if (UserContext != 0){ if (UserContext->memory != 0){ Free(UserContext->memory); } Free(UserContext); } return。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.