📄 syscall.c~
字号:
/* * System call handlers * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu> * Copyright (c) 2003,2004 David Hovemeyer <daveho@cs.umd.edu> * $Revision: 1.59 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". */#include <geekos/syscall.h>#include <geekos/errno.h>#include <geekos/kthread.h>#include <geekos/int.h>#include <geekos/elf.h>#include <geekos/malloc.h>#include <geekos/screen.h>#include <geekos/keyboard.h>#include <geekos/string.h>#include <geekos/user.h>#include <geekos/timer.h>#include <geekos/vfs.h>/* * Null system call. * Does nothing except immediately return control back * to the interrupted user program. * Params: * state - processor registers from user mode * * Returns: * always returns the value 0 (zero) */static int Sys_Null(struct Interrupt_State* state){ return 0;}/* * Exit system call. * The interrupted user process is terminated. * Params: * state->ebx - process exit code * Returns: * Never returns to user mode! */static int Sys_Exit(struct Interrupt_State* state){// TODO("Exit system call"); Exit(state->ebx);}/* * Print a string to the console. * Params: * state->ebx - user pointer of string to be printed * state->ecx - number of characters to print * Returns: 0 if successful, -1 if not */static int Sys_PrintString(struct Interrupt_State* state){// TODO("PrintString system call"); int rc = 0;
uint_t length = state->ecx;
uchar_t* buf = 0;
if (length > 0) {
/* Copy string into kernel. */
if ((rc = Copy_User_String(state->ebx, length, 1023, (char**) &buf)) != 0)
goto done;
/* Write to console. */
Put_Buf((const char*)buf, (ulong_t)length);
}
done:
if (buf != 0)
Free(buf);
return rc;}/* * Get a single key press from the console. * Suspends the user process until a key press is available. * Params: * state - processor registers from user mode * Returns: the key code */static int Sys_GetKey(struct Interrupt_State* state){// TODO("GetKey system call"); return Wait_For_Key();}/* * Set the current text attributes. * Params: * state->ebx - character attributes to use * Returns: always returns 0 */static int Sys_SetAttr(struct Interrupt_State* state){// TODO("SetAttr system call"); Set_Current_Attr((uchar_t) state->ebx); return 0;}/* * Get the current cursor position. * Params: * state->ebx - pointer to user int where row value should be stored * state->ecx - pointer to user int where column value should be stored * Returns: 0 if successful, -1 otherwise */static int Sys_GetCursor(struct Interrupt_State* state){// TODO("GetCursor system call"); int row, col; Get_Cursor(&row, &col); if (!Copy_To_User(state->ebx, &row, sizeof(int)) || !Copy_To_User(state->ecx, &col, sizeof(int))) return -1; return 0;}/* * Set the current cursor position. * Params: * state->ebx - new row value * state->ecx - new column value * Returns: 0 if successful, -1 otherwise */static int Sys_PutCursor(struct Interrupt_State* state){// TODO("PutCursor system call"); return Put_Cursor(state->ebx, state->ecx) ? 0 : -1;}/* * Create a new user process. * Params: * state->ebx - user address of name of executable * state->ecx - length of executable name * state->edx - user address of command string * state->esi - length of command string * Returns: pid of process if successful, error code (< 0) otherwise */static int Sys_Spawn(struct Interrupt_State* state){// TODO("Spawn system call"); int rc; char *program = 0; char *command = 0; struct Kernel_Thread *process; /* Copy program name and command from user space. */ if ((rc = Copy_User_String(state->ebx, state->ecx, VFS_MAX_PATH_LEN, &program)) != 0 || (rc = Copy_User_String(state->edx, state->esi, 1023, &command)) != 0) goto done; Enable_Interrupts(); /* * Now that we have collected the program name and command string * from user space, we can try to actually spawn the process. */ rc = Spawn(program, command, &process); if (rc == 0) { KASSERT(process != 0); rc = process->pid; } Disable_Interrupts();done: if (program != 0) Free(program); if (command != 0) Free(command); return rc;}/* * Wait for a process to exit. * Params: * state->ebx - pid of process to wait for * Returns: the exit code of the process, * or error code (< 0) on error */static int Sys_Wait(struct Interrupt_State* state){// TODO("Wait system call"); int exitCode; struct Kernel_Thread *kthread = Lookup_Thread(state->ebx); if (kthread == 0) return -12; Enable_Interrupts(); exitCode = Join(kthread); Disable_Interrupts(); return exitCode;}/* * Get pid (process id) of current thread. * Params: * state - processor registers from user mode * Returns: the pid of the current thread */static int Sys_GetPID(struct Interrupt_State* state){// TODO("GetPID system call"); return g_currentThread->pid;}/* * Set the scheduling policy. * Params: * state->ebx - policy, * state->ecx - number of ticks in quantum * Returns: 0 if successful, -1 otherwise */static int Sys_SetSchedulingPolicy(struct Interrupt_State* state){// TODO("SetSchedulingPolicy system call");}/* * Get the time of day. * Params: * state - processor registers from user mode * * Returns: value of the g_numTicks global variable */static int Sys_GetTimeOfDay(struct Interrupt_State* state){// TODO("GetTimeOfDay system call");}/* * Create a semaphore. * Params: * state->ebx - user address of name of semaphore * state->ecx - length of semaphore name * state->edx - initial semaphore count * Returns: the global semaphore id */static int Sys_CreateSemaphore(struct Interrupt_State* state){// TODO("CreateSemaphore system call");}/* * Acquire a semaphore. * Assume that the process has permission to access the semaphore, * the call will block until the semaphore count is >= 0. * Params: * state->ebx - the semaphore id * * Returns: 0 if successful, error code (< 0) if unsuccessful */static int Sys_P(struct Interrupt_State* state){// TODO("P (semaphore acquire) system call");}/* * Release a semaphore. * Params: * state->ebx - the semaphore id * * Returns: 0 if successful, error code (< 0) if unsuccessful */static int Sys_V(struct Interrupt_State* state){// TODO("V (semaphore release) system call");}/* * Destroy a semaphore. * Params: * state->ebx - the semaphore id * * Returns: 0 if successful, error code (< 0) if unsuccessful */static int Sys_DestroySemaphore(struct Interrupt_State* state){// TODO("DestroySemaphore system call");}/* * Global table of system call handler functions. */const Syscall g_syscallTable[] = { Sys_Null, Sys_Exit, Sys_PrintString, Sys_GetKey, Sys_SetAttr, Sys_GetCursor, Sys_PutCursor, Sys_Spawn, Sys_Wait, Sys_GetPID, /* Scheduling and semaphore system calls. */ Sys_SetSchedulingPolicy, Sys_GetTimeOfDay, Sys_CreateSemaphore, Sys_P, Sys_V, Sys_DestroySemaphore,};/* * Number of system calls implemented. */const int g_numSyscalls = sizeof(g_syscallTable) / sizeof(Syscall);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -