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

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

西北工业大学操作系统实验实验报告

一、实验目的

掌握在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 ====================

相关文档
最新文档