Exercise 7.Add a handler in the kernelfor interrupt vector T_SYSCALL
.You will have to edit kern/trapentry.S and kern/trap.c's trap_init()
. You also need to change trap_dispatch()
to handle thesystem call interrupt by calling syscall()
(defined in kern/syscall.c)with the appropriate arguments,and then arranging for the return value to be passed back to the user processin %eax
.Finally, you need to implement syscall()
inkern/syscall.c.Make sure syscall()
returns -E_INVAL
if the system call number is invalid.You should read and understand lib/syscall.c(especially the inline assembly routine) in order to confirm your understanding of the system call interface.You may also find it helpful to read inc/syscall.h.
A: Need to be very careful when dealing kernel code.
At first, when I finished this exercise, running hello will cause a vicious cycle in printing "hello world" endless. After tracing the code, I found that the tf->tf_eip always point to the "__start" in user code, which means the curenv->tf wasn't set well.
The root cause is when I set the SYSCALL handler, it should be TRAPHANDLER_NOEC(), but I used the TRAPHANDLER(), so it pushed one more byte into the tf->tf_eip.
Exercise 9.Change kern/trap.c
to panic if a page fault happens in kernel mode.
Hint: to determine whether a fault happened in user mode orin kernel mode, check the low bits of the tf_cs
.
Read user_mem_assert
in kern/pmap.c and implement user_mem_check
in that same file.
Change kern/syscall.c to sanity check argumentsto system calls.
Boot your kernel, running user/buggyhello.The environment should be destroyed,and the kernel should not panic.You should see:
[00001000] user_mem_check assertion failure for va 00000001 [00001000] free env 00001000 Destroyed the only environment - nothing more to do!
Finally, change debuginfo_eip
inkern/kdebug.c to call user_mem_check
onusd
, stabs
, andstabstr
. If you now runuser/breakpoint, you should be able to runbacktrace from the kernel monitor and see thebacktrace traverse into lib/libmain.c before thekernel panics with a page fault. What causes this page fault?You don't need to fix it, but you should understand why ithappens.
583 int
584 user_mem_check(struct Env *env, const void *va, size_t len, int perm)
585 {
586 // LAB 3: Jacky 140125.
587 uint32_t iter;
588 pte_t *pte;
589 if ((uint32_t)(va + len) >= ULIM) {
590 user_mem_check_addr = (uintptr_t)(va + len);
591 return -E_FAULT;
592 }
593 for (iter = (uint32_t)va; iter < (uint32_t)ROUNDUP((va + len), PGSIZE) ; iter += PGSIZE) {
594 pte = pgdir_walk(curenv->env_pgdir, (void *)iter, 0);
595 if ((*pte & perm) != perm) {
596 cprintf("Need perm = %x, but *pte is %x!\n", perm, *pt e);
597 user_mem_check_addr = iter;
598 return -E_FAULT;
599 }
600 }
601
602 return 0;
603 }