资源预览内容
第1页 / 共13页
第2页 / 共13页
第3页 / 共13页
第4页 / 共13页
第5页 / 共13页
第6页 / 共13页
第7页 / 共13页
第8页 / 共13页
第9页 / 共13页
第10页 / 共13页
亲,该文档总共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;/在堆分配方式下释放内存并再次初始化exeFileDataFree(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 elserc = 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%pn, kthread);Switch_To_Address_Space(userContext);/为用户态进程时则切换地址空间esp0 = (ulong_t) kthread-stackPage) + PAGE_SIZE;/if (userDebug)/ Print(S%lxn, 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+head-phentsize*head-phnum);KASSERT(head-entry%4=0);exeFormat-numSegments=head-phnum;exeFormat-entryAddr=head-entry;for(i=0;iphnum;i+)exeFormat-segmentListi.offsetInFile=proHeader-offset;exeFormat-segmentListi.lengthInFile=proHeader-fileSize;exeFormat-segmentListi.startAddress=proHeader-vaddr;exeFormat-segmentListi.sizeInMemory=proHeader-memSize;exeFormat-segmentListi.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-ldt0, (ulong_t) UserContext-memory, size / PAGE_SIZE, USER_PRIVILEGE ); /新建一个数据段 Init_Data_Segment_Descriptor( &UserContext-ldt1, (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); retu
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号