Geekos userseg.c
来源:互联网 发布:游戏充值平台源码 编辑:程序博客网 时间:2024/05/21 02:34
/* * Segmentation-based user mode implementation * Copyright (c) 2001,2003 David H. Hovemeyer <daveho@cs.umd.edu> * $Revision: 1.23 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". */#include <geekos/ktypes.h>#include <geekos/kassert.h>#include <geekos/defs.h>#include <geekos/mem.h>#include <geekos/string.h>#include <geekos/malloc.h>#include <geekos/int.h>#include <geekos/gdt.h>#include <geekos/segment.h>#include <geekos/tss.h>#include <geekos/kthread.h>#include <geekos/argblock.h>#include <geekos/user.h>/* ---------------------------------------------------------------------- * Variables * ---------------------------------------------------------------------- */#define DEFAULT_USER_STACK_SIZE 8192static 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->ldt[0], (ulong_t) UserContext->memory, size / PAGE_SIZE, USER_PRIVILEGE ); //新建一个数据段 Init_Data_Segment_Descriptor( &UserContext->ldt[1], (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); } return 0;}/* ---------------------------------------------------------------------- * Private functions * ---------------------------------------------------------------------- *//* * Create a new user context of given size *//* TODO: Implementstatic struct User_Context* Create_User_Context(ulong_t size)*/static bool Validate_User_Memory(struct User_Context* userContext, ulong_t userAddr, ulong_t bufSize){ ulong_t avail; if (userAddr >= userContext->size) return false; avail = userContext->size - userAddr; if (bufSize > avail) return false; return true;}/* ---------------------------------------------------------------------- * Public functions * ---------------------------------------------------------------------- *//* * Destroy a User_Context object, including all memory * and other resources allocated within it. */void Destroy_User_Context(struct User_Context* userContext){ //TODO("Destroy a User_Context"); //释放占用的LDT Free_Segment_Descriptor(userContext->ldtDescriptor); userContext->ldtDescriptor=0; //释放内存空间 Free(userContext->memory); userContext->memory=0; //释放userContext本身占用的内存 Free(userContext); userContext=0;}/* * Load a user executable into memory by creating a User_Context * data structure. * Params: * exeFileData - a buffer containing the executable to load * exeFileLength - number of bytes in exeFileData * exeFormat - parsed ELF segment information describing how to * load the executable's text and data segments, and the * code entry point address * command - string containing the complete command to be executed: * this should be used to create the argument block for the * process * pUserContext - reference to the pointer where the User_Context * should be stored * * Returns: * 0 if successful, or an error code (< 0) if unsuccessful */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");int i;ulong_t maxva = 0;//要分配的最大内存空间unsigned numArgs;//进程数目ulong_t argBlockSize;//参数块的大小ulong_t size, argBlockAddr;//参数块地址struct User_Context *userContext = 0;//计算用户态进程所需的最大内存空间for (i = 0; i < exeFormat->numSegments; ++i) {//elf.hstruct Exe_Segment *segment = &exeFormat->segmentList[i];ulong_t topva = segment->startAddress + segment->sizeInMemory; /* FIXME: range check */if (topva > maxva)maxva = topva;}Get_Argument_Block_Size(command, &numArgs, &argBlockSize);//获取参数块信息size = Round_Up_To_Page(maxva) + DEFAULT_USER_STACK_SIZE;argBlockAddr = size;size += argBlockSize;userContext = Create_User_Context(size);//按相应大小创建一个进程if (userContext == 0)//如果为核心态进程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;//成功}/* * Copy data from user memory into a kernel buffer. * Params: * destInKernel - address of kernel buffer * srcInUser - address of user buffer * bufSize - number of bytes to copy * * Returns: * true if successful, false if user buffer is invalid (i.e., * doesn't correspond to memory the process has a right to * access) */bool Copy_From_User(void* destInKernel, ulong_t srcInUser, ulong_t bufSize){ struct User_Context * UserContext = g_currentThread->userContext;//--: check if memory if validatedif (!Validate_User_Memory(UserContext,srcInUser, bufSize))return false;memcpy(destInKernel, UserContext->memory + srcInUser, bufSize); return true;}/* * Copy data from kernel memory into a user buffer. * Params: * destInUser - address of user buffer * srcInKernel - address of kernel buffer * bufSize - number of bytes to copy * * Returns: * true if successful, false if user buffer is invalid (i.e., * doesn't correspond to memory the process has a right to * access) */bool Copy_To_User(ulong_t destInUser, void* srcInKernel, ulong_t bufSize){struct User_Context * UserContext = g_currentThread->userContext;if (!Validate_User_Memory(UserContext, destInUser, bufSize))return false;memcpy(UserContext->memory + destInUser, srcInKernel, bufSize);return true;}/* * Switch to user address space belonging to given * User_Context object. * Params: * userContext - the User_Context */void Switch_To_Address_Space(struct User_Context *userContext){ ushort_t ldtSelector= userContext->ldtSelector;/* Switch to the LDT of the new user context */__asm__ __volatile__ ("lldt %0"::"a"(ldtSelector));}
阅读全文
0 0
- Geekos userseg.c
- Geekos user.c
- GeekOS-Project0
- GeekOS-Project1
- GeekOS project0
- geekos project4
- GeekOS Project3
- GeekOS Project2
- GeekOS Project2
- GeekOS Project3
- GeekOS project0
- Bochs搭建GeekOS平台
- geekOS操作系统(1)
- geekOs操作系统实验
- geekos项目project1代码
- GeekOS project1 -- 载入可执行文件
- GeekOS源代码学习(0)
- GeekOs系统调用
- 机房收费系统——组合查询
- Android setPolyToPoly遇到的问题(一)
- Linux下OpenCV的安装配置
- 链表的创建与节点的删除
- Programming Rust.pdf 英文原版 免费下载
- Geekos userseg.c
- 抽象类与接口的区别
- 用户名、密码等15个常用的js正则表达式
- adb常用命令
- 四层和七层负载均衡的区别
- HttpClient 主方法里面
- centos(7)-用户和组
- java应用——高仿XP画板(四:整个代码)
- 大神手册:优秀的iOS开发站点