?? user.c~
字號:
/* * Common user mode functions * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu> * $Revision: 1.50 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". */#include <geekos/errno.h>#include <geekos/ktypes.h>#include <geekos/kassert.h>#include <geekos/int.h>#include <geekos/mem.h>#include <geekos/malloc.h>#include <geekos/kthread.h>#include <geekos/vfs.h>#include <geekos/tss.h>#include <geekos/user.h>/* * This module contains common functions for implementation of user * mode processes. *//* * Associate the given user context with a kernel thread. * This makes the thread a user process. */void Attach_User_Context(struct Kernel_Thread* kthread, struct User_Context* context){ KASSERT(context != 0); kthread->userContext = context; Disable_Interrupts(); /* * We don't actually allow multiple threads * to share a user context (yet) */ KASSERT(context->refCount == 0); ++context->refCount; Enable_Interrupts();}/* * If the given thread has a user context, detach it * and destroy it. This is called when a thread is * being destroyed. */void Detach_User_Context(struct Kernel_Thread* kthread){ struct User_Context* old = kthread->userContext; kthread->userContext = 0; if (old != 0) { int refCount; Disable_Interrupts(); --old->refCount; refCount = old->refCount; Enable_Interrupts(); /*Print("User context refcount == %d\n", refCount);*/ if (refCount == 0) Destroy_User_Context(old); }}/* * Spawn a user process. * Params: * program - the full path of the program executable file * command - the command, including name of program and arguments * pThread - reference to Kernel_Thread pointer where a pointer to * the newly created user mode thread (process) should be * stored * Returns: * The process id (pid) of the new process, or an error code * if the process couldn't be created. Note that this function * should return ENOTFOUND if the reason for failure is that * the executable file doesn't exist. */////////////////////////////////int Spawn(const char *program, const char *command, struct Kernel_Thread **pThread){ int result; char *exeFileData = 0; ulong_t exeFileLength; struct User_Context *UserContext = 0; struct Exe_Format exeFormat; struct Kernel_Thread * thread; Print("there is here\n"); if ((result = Read_Fully(program,(void **) &exeFileData, &exeFileLength)) != 0) { Print("Failed to read file %s\n", program); goto fail; } if ((result = Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat)) != 0) { Print("Failed to parse ELF file \n"); goto fail; } if ((result = Load_User_Program(exeFileData, exeFileLength, &exeFormat, command, &UserContext)) != 0) { Print("Failed to Load User Program\n"); goto fail; } Free(exeFileData); exeFileData = 0; thread = Start_User_Thread(UserContext, false); if (thread != 0) { *pThread = thread; result = thread->pid; } else { result = ENOMEM; } return result;fail: if (exeFileData != 0) { Print("free(exeFileData)\n"); Free(exeFileData); } if (UserContext != 0) { Print("Destroy_User_Context(UserContext);\n"); Destroy_User_Context(UserContext); } return result;}/* * 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. */ struct User_Context * UserContext = kthread->userContext; if (UserContext == 0) { return ; } Switch_To_Address_Space(UserContext); Set_Kernel_Stack_Pointer((ulong_t)(kthread->stackPage + PAGE_SIZE)); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -