From 6d6fdbea5c215812f696d0fbdb8d210af467623f Mon Sep 17 00:00:00 2001 From: Guanqun Lu Date: Tue, 11 Mar 2008 23:02:03 +0800 Subject: [PATCH] lab3 finished Signed-off-by: Guanqun Lu --- kern/init.c | 2 +- kern/pmap.c | 26 ++++++++++++++++++++++++++ kern/syscall.c | 26 ++++++++++++++++++++++---- kern/trap.c | 22 +++++++++++++++++++++- kern/trapentry.S | 1 + lib/libmain.c | 5 ++++- 6 files changed, 75 insertions(+), 7 deletions(-) diff --git a/kern/init.c b/kern/init.c index 11f8f33..ec2a36c 100644 --- a/kern/init.c +++ b/kern/init.c @@ -41,7 +41,7 @@ i386_init(void) ENV_CREATE2(TEST, TESTSIZE); #else // Touch all you want. - ENV_CREATE(user_breakpoint); + ENV_CREATE(user_hello); #endif // TEST* // We only have one user environment for now, so just run it. diff --git a/kern/pmap.c b/kern/pmap.c index 87f5f62..a613d5f 100644 --- a/kern/pmap.c +++ b/kern/pmap.c @@ -775,6 +775,32 @@ int user_mem_check(struct Env *env, const void *va, size_t len, int perm) { // LAB 3: Your code here. + unsigned int va_start, va_end; + pte_t *pte; + + perm |= PTE_P; + user_mem_check_addr = (uintptr_t)va; + // make 'va_start' and 'va_end' page-aligned. + va_start = ROUNDDOWN((unsigned int)va, PGSIZE); + va_end = ROUNDUP((unsigned int)(va + len), PGSIZE); + + while (va_start < va_end) { + // check whether the address is below ULIM + if (va_start >= ULIM) + return -E_FAULT; + + // check the page table permission + pte = pgdir_walk(env->env_pgdir, (void *)va_start, 0); + if (!pte) + return -E_FAULT; + + if ((*pte & perm) != perm) + return -E_FAULT; + + // update 'va_start' and 'user_mem_check_addr' + va_start += PGSIZE; + user_mem_check_addr = va_start; + } return 0; } diff --git a/kern/syscall.c b/kern/syscall.c index cb60704..5727106 100644 --- a/kern/syscall.c +++ b/kern/syscall.c @@ -19,8 +19,8 @@ sys_cputs(const char *s, size_t len) { // Check that the user has permission to read memory [s, s+len). // Destroy the environment if not. - // LAB 3: Your code here. + user_mem_assert(curenv, (void *)s, len, 0); // Print the string supplied by the user. cprintf("%.*s", len, s); @@ -69,8 +69,6 @@ sys_env_destroy(envid_t envid) return 0; } - - // Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) @@ -78,7 +76,27 @@ syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. + int ret = 0; + + switch (syscallno) { + case SYS_cputs: + sys_cputs((const char *)a1, (size_t)a2); + break; + case SYS_cgetc: + ret = sys_cgetc(); + break; + case SYS_getenvid: + ret = sys_getenvid(); + break; + case SYS_env_destroy: + ret = sys_env_destroy((envid_t)a1); + break; + default: + // NSYSCALLS + ret = -E_INVAL; + break; + } - panic("syscall not implemented"); + return ret; } diff --git a/kern/trap.c b/kern/trap.c index 9c029fc..38319fc 100644 --- a/kern/trap.c +++ b/kern/trap.c @@ -77,6 +77,8 @@ idt_init(void) extern void mchk_entry(); extern void simderr_entry(); + extern void syscall_entry(); + // LAB 3: Your code here. SETGATE(idt[T_DIVIDE], 1, GD_KT, divzero_entry, 0); SETGATE(idt[T_DEBUG], 1, GD_KT, debug_entry, 0); @@ -97,6 +99,8 @@ idt_init(void) SETGATE(idt[T_MCHK], 1, GD_KT, mchk_entry, 0); SETGATE(idt[T_SIMDERR], 1, GD_KT, simderr_entry, 0); + SETGATE(idt[T_SYSCALL], 0, GD_KT, syscall_entry, 3); + // Setup a TSS so that we get the right stack // when we trap to the kernel. ts.ts_esp0 = KSTACKTOP; @@ -148,6 +152,8 @@ trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. + int sys_ret; + switch (tf->tf_trapno) { case T_BRKPT: print_trapframe(tf); @@ -156,6 +162,15 @@ trap_dispatch(struct Trapframe *tf) case T_PGFLT: page_fault_handler(tf); break; + case T_SYSCALL: + sys_ret = syscall(tf->tf_regs.reg_eax, + tf->tf_regs.reg_edx, + tf->tf_regs.reg_ecx, + tf->tf_regs.reg_ebx, + tf->tf_regs.reg_edi, + tf->tf_regs.reg_esi); + tf->tf_regs.reg_eax = sys_ret; + return; default: break; } @@ -204,8 +219,13 @@ page_fault_handler(struct Trapframe *tf) fault_va = rcr2(); // Handle kernel-mode page faults. - // LAB 3: Your code here. + if ((tf->tf_cs & 3) == 0) { + // trapped from kernel mode + // and we are in trouble... + panic("page fault happend in kernel mode"); + return; + } // We've already handled kernel-mode exceptions, so if we get here, // the page fault happened in user mode. diff --git a/kern/trapentry.S b/kern/trapentry.S index c7685c4..ce4904d 100644 --- a/kern/trapentry.S +++ b/kern/trapentry.S @@ -59,6 +59,7 @@ TRAPHANDLER(align_entry, T_ALIGN); TRAPHANDLER_NOEC(mchk_entry, T_MCHK); TRAPHANDLER_NOEC(simderr_entry, T_SIMDERR); +TRAPHANDLER_NOEC(syscall_entry, T_SYSCALL); /* * Lab 3: Your code here for _alltraps diff --git a/lib/libmain.c b/lib/libmain.c index e5c3bf4..b296a8c 100644 --- a/lib/libmain.c +++ b/lib/libmain.c @@ -13,7 +13,10 @@ libmain(int argc, char **argv) { // set env to point at our env structure in envs[]. // LAB 3: Your code here. - env = 0; + envid_t envid; + + envid = sys_getenvid(); + env = &envs[ENVX(envid)]; // save the name of the program so that panic() can use it if (argc > 0) -- 2.11.4.GIT