}
if (Spawn_Program(exeFileData, &exeFormat) != 0) {
Print(\); goto fail; } /*
* User program has been loaded, so we can free the * executable file data now. */
Free(exeFileData); exeFileData = 0;
/* If we arrived here, everything was fine and the program exited */ Print(\); Print(\); Exit(0); fail:
/* We failed; release any allocated memory */ Disable_Interrupts(); Free(virtSpace); Enable_Interrupts(); }
(三) project2的设计
1.设计原理
Entry.c为用户程序外壳,用户程序的入口就在这里,并与用户程序一起编译。再根据传递的中断向量查找并调用相关的中断处理程序,并实现调度进程的选择。
2.运行原理
(1) user.C文件中的函数Spawn(),其功能是生成一个新的用户级进程。
(2) 再用函数Switch_To_User_Context(),调度程序在执行一个新的进程前调用该函数以
切换用户的地址空间。
(3) 函数Parse_ELF_Executable()实现要求同项目1。
(4) Userseg.c文件是实现一些为实现对user.c中高层操作支持的函数。其中包括:释放
用户态进程占用的内存资源、通过加载可执行文件镜像创建新进程的User_Context结构、在用户地址空间和内核地址空间之间复制数据、通过将进程的LDT装入到LDT寄存器来激活用户的地址空间。
(5) 为进程初始化内核堆栈,其函数为Setup_User_Thread()。同时创建用户上下问对象,
其函数为Start_User_Thread()。
(6) Kthread.c文件主要是实现用户程序要求内核进行服务的一些系统调用函数定义。
(7) 内核线程的建立流程:
Spawn_Init_Process() Start_Kernel_Thread() Spawner() Read_Fully() Parse_ELF_Executable() Spawn_Program()
(图 1)
3.运行结果
(项目 2)
4.核心代码
int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength, struct Exe_Format *exeFormat) {
//By CQQ;2007-08-27---------------------------------------
int i;
elfheader=(elfHeader *)Malloc(sizeof(*elfheader)); { }
memcpy(elfheader,exeFileData,sizeof(*elfheader));
Print(\); return 1;
elfHeader *elfheader; if (elfheader==0)
exeFormat->numSegments=elfheader->phnum; //By CQQ;ELF文件的段的个数;
exeFormat->entryAddr=elfheader->entry; //BY CQQ;代码入//Print(\for (i=0;i
programHeader *phearder; if (phearder==0) { }
Print(\); return 1;
口地址;
phearder=(programHeader *)Malloc(sizeof(*phearder));
memcpy(phearder,exeFileData+sizeof(*elfheader)+i*sizeof(*phearder),sizeof(*phearder)); struct Exe_Segment *segment = &exeFormat->segmentList[i];
segment->offsetInFile=phearder->offset; //BY CQQ;段的偏移量;
segment->lengthInFile=phearder->fileSize; //BY CQQ;段在文件中所占的大小; }
int Spawn(const char *program, const char *command, struct Kernel_Thread **pThread) { /* * Hints:
* - Call Read_Fully() to load the entire executable into a memory buffer
} return 0;
segment->startAddress=phearder->vaddr; //BY CQQ;段在内存中的地址, segment->sizeInMemory=phearder->memSize; //BY CQQ;段在内存中的大小; segment->protFlags=phearder->flags; //BY CQQ;段的相关标志;
虚拟地址;
* - Call Parse_ELF_Executable() to verify that the executable is * valid, and to populate an Exe_Format data structure describing * how the executable should be loaded
* - Call Load_User_Program() to create a User_Context with the loaded * program
* - Call Start_User_Thread() with the new User_Context *
* If all goes well, store the pointer to the new thread in * pThread and return 0. Otherwise, return an error code. */
//By CQQ;---------------------------------------------------------------------- int rc=0;
char *exeFileData = 0; ulong_t exeFileLength; struct Exe_Format exeFormat;
struct User_Context *pUserContext=0;
if (Read_Fully(program, (void**) &exeFileData, &exeFileLength) != 0) struct Kernel_Thread *uThread=0; {
Print(\, program); goto fail; }
if (Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat) != 0) {
Print(\); goto fail; }
if (Load_User_Program(exeFileData, exeFileLength, &exeFormat, command, { }
Free(exeFileData);
uThread=Start_User_Thread(pUserContext, false); if (uThread==0) { }
KASSERT(uThread->refCount == 2); /* Return Kernel_Thread pointer */
rc = ENOMEM;
Print(\); //goto fail;
Print(\);
&pUserContext)!= 0)
goto fail;
exeFileData = 0;
*pThread=uThread; return rc; fail:
if (exeFileData != 0) {
Free(exeFileData); } { } return rc; } /*
* If the given thread has a User_Context, * switch to its memory space. *
* Params:
* kthread - the thread that is about to execute
* state - saved processor registers describing the state when * the thread was interrupted */
void Switch_To_User_Context(struct Kernel_Thread* kthread, struct Interrupt_State* state) { /*
* Hint: Before executing in user mode, you will need to call
* the Set_Kernel_Stack_Pointer() and Switch_To_Address_Space() * functions. */
//By CQQ;-------------------------------------------------------------------------- static struct User_Context* mUserContext;
struct User_Context* userContext = kthread->userContext;
if (userContext == 0)
Set_Kernel_Stack_Pointer(((ulong_t) kthread->stackPage) + PAGE_SIZE);
if (userContext != mUserContext) {
return;
KASSERT(!Interrupts_Enabled());
Destroy_User_Context(pUserContext); exeFileData=0;
if (pUserContext != 0)
pUserContext=0;
Switch_To_Address_Space(userContext); //By CQQ;用户地址空间;
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库geekos计算机系统软件实验报告(3)在线全文阅读。
相关推荐: