《计算机操作系统实验运行用户态程序》由会员分享,可在线阅读,更多相关《计算机操作系统实验运行用户态程序(23页珍藏版)》请在金锄头文库上搜索。
1、西北工业大学操作系统实验 实验报告一、实验目的掌握在GeekOS系统用户态模式下加载并运行可执行程序的方法。二、实验要求1.按照实验讲义P127页中的设计要求,实现在用户态模式下加载并运行 可执行程序的代码,给出关键函数的代码以及实验结果。三、实验过程及结果答:核心函数代码如下:= user.c =/产生一个进程(用户态)int Spawn(const char *program, const char *command,struct Kernel_Thread*pThread)/TODO(Spaw n a process by readi ng an executable from a fi
2、lesystem);int rc;char *exeFileData = 0;ulong_t exeFileLe ngth;struct User_C on text *userC on text = 0;struct Kern el_Thread *process = 0;struct Exe_Format exeFormat;if (rc = Read_Fully(program, (void*) &exeFileData, &exeFileLe ngth) != 0 )Print(Failed to Read File %s!n, program);goto fail;if(rc = P
3、arse_ELF_Executable(exeFileData, exeFileLe ngth, &exeFormat) != 0 )Prin t(Failed to Parse ELF File!n);goto fail;if(rc = Load_User_Program(exeFileData, exeFileLe ngth, &exeFormat, comma nd,& userCo ntext) != 0)Prin t(Failed to Load User Program!n);goto fail;/在堆分配方式下释放内存并再次初始化exeFileDataFree(exeFileDa
4、ta);exeFileData = 0;/*开始用户进程,调用Start_User_Thread函数创建一个进程并使其进入准备运行队列*/process = Start_User_Thread(userC on text, false);if (process != 0) KASSERT(process-refCou nt = 2);/*返回核心进程的指针 */*pThread = process;rc = process-pid;记录当前进程的 ID elserc = ENOMEM;return rc;fail: /如果新进程创建失败则注销User_Context 对象if (exeFile
5、Data != 0)Free(exeFileData);/ 释放内存if (userCo ntext != 0)Destroy_User_Co ntext(userCo ntext);/销毁进程对象return rc;/切换至用户上下文structvoidSwitch_To_User_C on text(structKernel_Thread*kthread,In terrupt_State* state)static struct User_C on text* s_curre ntUserC on text; /* last user con text used */exter n int
6、 userDebug;struct User_C on text* userC on text = kthread-userC on text;KASSERT(!I nterrupts_E nabled();if (userC on text = 0) /userCo ntext为0表示此进程为核心态进程就不用切换地址空间return;if (userC on text != s_curre ntUserC on text) ulong_t esp0;/if (userDebug) Print(A%pn, kthread);Switch_To_Address_Space(userCo ntex
7、t);/为用户态进程时则切换地址空间esp0 = (ul ong_t) kthread-stackPage) + PAGE_SIZE;/if (userDebug)/ Prin t(S%lxn, esp0);/*新进程的核心栈 */Set_Kernel_Stack_Poi nter(espO);/ 设置内核堆栈指针/* New user con text is active */s_curre ntUserC on text = userC on text;= elf.c =int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileL
8、e ngth, structExe_Format *exeFormat)int i;elfHeader *head=(elfHeader*)exeFileData;programHeader *proHeader=(programHeader *)(exeFileData+head-phoff);KASSERT(exeFileData!=NULL);KASSERT(exeFileLe ngthhead-ehsize+head-phe ntsize*head-ph nu m);KASSERT(head-e ntry%4=0);exeFormat- nu mSegme nts=head-ph nu
9、m;exeFormat-e ntryAddr=head-e ntry;for(i=0;iph nu m;i+)exeFormat-segme ntListi.offsetl nF ile=proHeader-offset;exeFormat-segme ntListi.le ngthl nFile=proHeader-fileSize;exeFormat-segme ntListi.startAddress=proHeader-vaddr;exeFormat-segme ntListi.sizel nM emory=proHeader-memSize;exeFormat-segme ntLis
10、ti.protFlags=proHeader-flags; proHeader+;return 0;= userseg.c =/需在此文件各函数前增加一个函数,此函数的功能是按给定的大小创建一个用户级进程上下文,具体实现如下:/函数功能:按给定的大小创建一个用户级进程上下文static struct User_C on text* Create_User_C on text(u long_t size)struct User_C on text * UserC on text;size = Roun d_Up_To_Page(size);UserCo ntext = (struct User_
11、Co ntext *)Malloc(sizeof(struct User_Co ntext); if (UserCo ntext != 0)UserC on text-memory = Malloc(size);/为核心态进程elsegoto fail;/内存为空if (0 = UserC on text-memory)goto fail;memset(UserC on text-memory, 0, size);UserC on text-size = size;/以下为用户态进程创建LDT(段描述符表)/新建一个LDT描述符UserC on text-ldtDescriptor = All
12、ocate_Segme nt_Descriptor();goto fail;/初始化段描述符In it_LDT_Descriptor(UserCo ntext-ldtDescriptor,UserCo ntext-ldt,NUM_USER_LDT_ENTRIES);/新建一个LDT选择子UserC on text-ldtSelector=Selector(KERNEL_PRIVILEGE,true,Get_Descriptor_I ndex(UserC on text-ldtDescriptor);/新建一个文本段描述符Ini t_Code_Segme nt_Descriptor(& User
13、Co ntext-ldt0,(ulon g_t) UserC on text-memory,size / PAGE_SIZE,USER_PRIVILEGE);/新建一个数据段Ini t_Data_Segme nt_Descriptor(& UserCo ntext-ldt1,(ulon g_t) UserC on text-memory,size / PAGE_SIZE,USER_PRIVILEGE);/新建数据段和文本段选择子UserCo ntext-dsSelector = Selector(USER_PRIVILEGE, false, 1);/将引用数清0UserC on text-re
14、fCou nt = 0;retur n UserC on text;fail:if (UserCo ntext != 0)if (UserC on text-memory != 0)Free(UserC on text-memory);Free(UserC on text);return 0;/摧毁用户上下文void Destroy_User_C on text(struct User_C on text* userC on text) /TODO(Destroy a User_Co ntext);/释放占用的LDTFree_Segme nt_Descriptor(userC on text-ldtDescriptor);/释放内存空间Free(userC on text-memory);userC on text-memory=0;/释放userContext 本身占用的内存Free(userC on text);userC on text=0;int Load_User_Program(char*exe