Exercises:
diff --git a/kern/syscall.c b/kern/syscall.c
index 414d489..d1c3e5e 100644
--- a/kern/syscall.c
+++ b/kern/syscall.c
@@ -69,10 +69,16 @@ 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.
-
- panic("syscall not implemented");
-
+ // albert create
switch (syscallno) {
+ case SYS_cputs:
+ sys_cputs((const char*)a1,a2);
+ case SYS_genenvid:
+ return SYS_genenvid();
+ case SYS_cgetc:
+ return sys_cgetc();
+ case SYS_env_destroy:
+ return sys_env_destroy((envid_t)a1);
default:
return -E_INVAL;
}
diff --git a/kern/trap.c b/kern/trap.c
index e27b556..8f12c31 100644
--- a/kern/trap.c
+++ b/kern/trap.c
@@ -65,6 +65,28 @@ trap_init(void)
extern struct Segdesc gdt[];
// LAB 3: Your code here.
+ // albert create
+ SETGATE(idt[T_DIVIDE], true, GD_KT,t_divide, 0);
+ SETGATE(idt[T_DEBUG], true, GD_KT,t_debug, 0);
+ SETGATE(idt[T_NMI], false, GD_KT,t_nmi, 0);
+ SETGATE(idt[T_BRKPT], true, GD_KT,t_brkpt, 3);
+ SETGATE(idt[T_OFLOW], true, GD_KT,t_oflow, 0);
+ SETGATE(idt[T_BOUND], true, GD_KT,t_bound, 0);
+ SETGATE(idt[T_ILLOP], true, GD_KT,t_illop, 0);
+ SETGATE(idt[T_DEVICE], true, GD_KT,t_device, 0);
+ SETGATE(idt[T_DBLFLT], false, GD_KT,t_dblflt, 0);
+ SETGATE(idt[T_TSS], true, GD_KT,t_tss, 0);
+ SETGATE(idt[T_SEGNP], true, GD_KT,t_segnp, 0);
+ SETGATE(idt[T_STACK], true, GD_KT,t_stack, 0);
+ SETGATE(idt[T_GPFLT], true, GD_KT,t_gpflt, 0);
+ SETGATE(idt[T_PGFLT], true, GD_KT,t_pgflt, 0);
+ SETGATE(idt[T_FPERR], true, GD_KT,t_fperr, 0);
+ SETGATE(idt[T_ALIGN], true, GD_KT,t_align, 0);
+ SETGATE(idt[T_MCHK], false, GD_KT,t_mchk, 0);
+ SETGATE(idt[T_SIMDERR], true, GD_KT,t_simderr, 0);
+
+ SETGATE(idt[T_SYSCALL], true, GD_KT, t_syscall, 3);
+
// Per-CPU setup
trap_init_percpu();
@@ -144,6 +166,25 @@ trap_dispatch(struct Trapframe *tf)
{
// Handle processor exceptions.
// LAB 3: Your code here.
+ // albert create
+ if(tf->tf_trapno == T_PGFLT){
+ page_fault_handler(tf);
+ return 0;
+ }else if(tf->tf_trapno == T_BRKPT){
+ monitor(tf);
+ return;
+ }else if(tf->tf_trapno == T_SYSCALL){
+ struct PushRegs *regs = &curent->env_tf.tf_regs;
+ cprintf("syscall disapatched! %d\n",regs->reg_eax);
+ int32_t result = syscall(regs->reg_eax,
+ regs->reg_edx,
+ regs->reg_ecx,
+ regs->reg_ebx,
+ regs->reg_edi,
+ regs->reg_esi);
+ regs->reg_eax = result;
+ return;
+ }
// Unexpected trap: The user process or the kernel has a bug.
print_trapframe(tf);
@@ -205,6 +246,10 @@ page_fault_handler(struct Trapframe *tf)
// Handle kernel-mode page faults.
// LAB 3: Your code here.
+ // albert create
+ if((tf->tf_cs & 3) == 0){
+ panic("kernel page fault at:%x",fault_va);
+ }
// We've already handled kernel-mode exceptions, so if we get here,
// the page fault happened in user mode.
diff --git a/kern/trap.h b/kern/trap.h
index 36b8758..135d482 100644
--- a/kern/trap.h
+++ b/kern/trap.h
@@ -20,4 +20,32 @@ void print_trapframe(struct Trapframe *tf);
void page_fault_handler(struct Trapframe *);
void backtrace(struct Trapframe *);
+/*
+ *albert create
+ awk code to generate these definitions:
+ awk '{print "void "tolower($2)"();"}'
+*/
+
+void t_divide();
+void t_debug();
+void t_nmi();
+void t_brkpt();
+void t_oflow();
+void t_bound();
+void t_illop();
+void t_device();
+void t_dblflt();
+void t_tss();
+void t_segnp();
+void t_stack();
+void t_gpflt();
+void t_pgflt();
+void t_fperr();
+void t_align();
+void t_mchk();
+void t_simderr();
+
+void t_syscall();
+void t_default();
+
#endif /* JOS_KERN_TRAP_H */
diff --git a/kern/trapentry.S b/kern/trapentry.S
index 22fc640..d3bfd51 100644
--- a/kern/trapentry.S
+++ b/kern/trapentry.S
@@ -46,6 +46,28 @@
/*
* Lab 3: Your code here for generating entry points for the different traps.
*/
+ /*albert create*/
+ TRAPHANDLER_NOEC(t_divide,T_DIVIDE);
+ TRAPHANDLER_NOEC(t_debug,T_DEBUG);
+ TRAPHANDLER_NOEC(t_nmi,T_NMI);
+ TRAPHANDLER_NOEC(t_brkpt,T_BRKPT);
+ TRAPHANDLER_NOEC(t_oflow,T_OFLOW);
+ TRAPHANDLER_NOEC(t_bound,T_BOUND);
+ TRAPHANDLER_NOEC(t_illop,T_ILLOP);
+ TRAPHANDLER_NOEC(t_device,T_DEVICE);
+ TRAPHANDLER(t_dblflt, T_DBLFLT);
+ TRAPHANDLER(t_tss, T_TSS);
+ TRAPHANDLER(t_segnp, T_SEGNP);
+ TRAPHANDLER(t_stack, T_STACK);
+ TRAPHANDLER(t_gpflt, T_GPFLT);
+ TRAPHANDLER(t_pgflt, T_PGFLT);
+ TRAPHANDLER_NOEC(t_fperr, T_FPERR);
+ TRAPHANDLER(t_align, T_ALIGN);
+ TRAPHANDLER_NOEC(t_mchk, T_MCHK);
+ TRAPHANDLER_NOEC(t_simderr, T_SIMDERR);
+
+ TRAPHANDLER_NOEC(t_syscall, T_SYSCALL);
+ TRAPHANDLER_NOEC(t_default, T_DEFAULT);
@@ -53,3 +75,12 @@
* Lab 3: Your code here for _alltraps
*/
+_alltraps:
+ pushl %ds
+ pushl %es
+ pushal
+ movw $GD_KD,%ax
+ movw %ax,%ds
+ movw %ax,%es
+ pushl %esp
+ call trap
执行编译命令:
1.make V=1 grade
Verbose mode. Print out every command being executed, including arguments.Stop after any failed grade test and leave the QEMU output in jos.out for inspection.
2.make run-name
Run user program name. For example, make run-hello runs user/hello.c. make run-name-nox, run-name-gdb, run-name-gdb-nox.
3…/grade-lab3
Handling Page Fault,异常号为14。当缺页中断发生时,系统会把引起中断的线性地址存放到控制寄存器 CR2 中。在trap.c 中,已经提供了一个能够处理这种缺页异常的函数page_fault_handler()。
System calls使用int指令实现系统调用,使用0x30作为中断号。应用使用寄存器传递系统调用号和参数。系统调用号保存在%eax,五个参数依次保存在%edx, %ecx, %ebx, %edi, %esi中。返回值保存在%eax中。
Breaking Points Exception,interrupt vector 3 (T_BRKPT), is normally used to allow debuggers to insert breakpoints in a program’s code by temporarily replacing the relevant program instruction with the special 1-byte int3 software interrupt instruction. The user-mode implementation of panic() in lib/panic.c, for example, performs an int 3 after displaying its panic message.
//在kernel monitor中添加支持GDB式的调试c, si及x
diff --git a/kern/monitor.c b/kern/monitor.c
index 4e00796..60a98c0 100644
--- a/kern/monitor.c
+++ b/kern/monitor.c
@@ -25,8 +25,51 @@ struct Command {
static struct Command commands[] = {
{ "help", "Display this list of commands", mon_help },
{ "kerninfo", "Display information about the kernel", mon_kerninfo },
+ //albert
+ {"c","Continue execution from the current location",mon_c},
+ {"si","Execute the code instruction by instruction",mon_si},
+ {"x","Display the memory",mon_x},
};
+
+int mon_c(int argc,char **argv,struct Trapframe *tf)
+{
+ if(argc != 1){
+ cprintf("Usage:c\n");
+ }
+
+ tf->tf_eflags &= ~FL_TF;
+ env_run(curenv);
+ return 0;
+}
+
+
+int mon_si(int argc,char **argv,struct Trapframe *tf)
+{
+ if(argc != 1){
+ cprintf("Usage:si\n");
+ }
+
+ tf->tf_eflags |= FL_TF;
+ cprintf("tf_eip=0x%x\n",tf->tf_eip);
+ env_run(curenv);
+ return 0;
+
+}
+
+int mon_x(int argc,char **argv,struct Trapframe *tf)
+{
+ if(argc != 2){
+ cprintf("Usage:x [address]\n");
+ return 0;
+ }
+
+ uint32_t addr = strtol(argv[1],NULL,16);
+ cprintf("%08p:\t%u\n",addr,*((uint32_t *)addr));
+ return 0;
+}
+
+
/***** Implementations of basic kernel monitor commands *****/
int
diff --git a/kern/monitor.h b/kern/monitor.h
index 0aa0f26..a1f6409 100644
--- a/kern/monitor.h
+++ b/kern/monitor.h
@@ -15,5 +15,8 @@ void monitor(struct Trapframe *tf);
int mon_help(int argc, char **argv, struct Trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct Trapframe *tf);
int mon_backtrace(int argc, char **argv, struct Trapframe *tf);
+int mon_c(int argc, char **argv, struct Trapframe *tf);
+int mon_si(int argc, char **argv, struct Trapframe *tf);
+int mon_x(int argc, char **argv, struct Trapframe *tf);
#endif // !JOS_KERN_MONITOR_H
执行make qemu进行调试。
K> kerninfo
Special kernel symbols:
_start 0010000c (phys)
entry f010000c (virt) 0010000c (phys)
etext f01077b7 (virt) 001077b7 (phys)
edata f0190932 (virt) 00190932 (phys)
end f0191830 (virt) 00191830 (phys)
Kernel executable memory footprint: 583KB
K>