代码如下:
int Load_User_Program(char *exeFileData, ulong_t exeFileLength,
struct Exe_Format *exeFormat, const char *command,
struct User_Context **pUserContext)
{
// TODO("Load a user executable into a user memory space using segmentation");
unsigned int i;
struct User_Context *userContext = NULL;
/* 要分配的最大内存空间 */
ulong_t maxva = 0;
/* 计算用户态进程所需的最大内存空间 */
for (i = 0; i < exeFormat->numSegments; i++)
{
struct Exe_Segment *segment = &exeFormat->segmentList[i];
ulong_t topva = segment->startAddress + segment->sizeInMemory;
if (topva > maxva) maxva = topva;
}
/* 程序参数数目 */
unsigned int numArgs;
/* 获取参数块的大小 */
ulong_t argBlockSize;
Get_Argument_Block_Size(command, &numArgs, &argBlockSize);
/* 用户进程大小 = 参数块总大小 + 进程堆栈大小(8192) */
ulong_t size = Round_Up_To_Page(maxva) + DEFAULT_USER_STACK_SIZE;
/* 参数块地址 */
ulong_t argBlockAddr = size;
size += argBlockSize;
/* 按相应大小创建一个进程 */
userContext = Create_User_Context(size);
/* 如果进程创建失败则返回错误信息 */
if (userContext == NULL)
{
return -1;
}
/* 将用户程序中的各段内容复制到分配的用户内存空间 */
for (i = 0; i < exeFormat->numSegments; i++)
{
struct Exe_Segment *segment = &exeFormat->segmentList[i];
memcpy(userContext->memory + segment->startAddress,
exeFileData + segment->offsetInFile,
segment->lengthInFile);
}
/* 格式化参数块 */
Format_Argument_Block(userContext->memory + argBlockAddr, numArgs, argBlockAddr, command);
/* 初始化数据段、堆栈段及代码段信息 */
userContext->entryAddr = exeFormat->entryAddr;
userContext->argBlockAddr = argBlockAddr;
userContext->stackPointerAddr = argBlockAddr;
/* 将初始化完毕的 User_Context 赋给*pUserContext */
*pUserContext = userContext;
return 0;
}