xv6 lab3实验

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> 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值