ucore lab1
练习5:实现函数调用堆栈跟踪函数 (需要编程)
我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_stackframe来跟踪函 数调用堆栈中记录的返回地址。在如果能够正确实现此函数,可在lab1中执行 “make qemu”后,在qemu模拟器中得到类似如下的输出:
尝试添加代码:
//galaxy 2014-7-12 uint32_t ebp_value,eip_value; ebp_value=read_ebp(); while(ebp_value!=0) { cprintf("ebp: 0x%08x \n",ebp_value); ebp_value = *(uintptr_t *)ebp_value; }

//galaxy 2014-7-12 uint32_t ebp_value,func_retaddr; ebp_value = read_ebp(); func_retaddr = read_eip(); while(ebp_value!=0) { cprintf("ebp: 0x%08x eip: 0x%08x args: 0x%08x 0x%08x 0x%08x 0x%08x \n",ebp_value,func_retaddr, *(uintptr_t *)(ebp_value+8),*(uintptr_t *)(ebp_value+12),*(uintptr_t *)(ebp_value+16), *(uintptr_t *)(ebp_value+20)); cprintf("\n"); print_debuginfo(func_retaddr); ebp_value = *(uintptr_t *)ebp_value; func_retaddr = *(uintptr_t *)(ebp_value+4); }
(THU.CST) os is loading ...
Special kernel symbols:
entry 0x00100000 (phys)
etext 0x0010329b (phys)
edata 0x0010ea16 (phys)
end 0x0010fd20 (phys)
Kernel executable memory footprint: 64KB
ebp: 0x00007b08 eip: 0x001009a2 args: 0x00010094 0x00000000 0x00007b38 0x0010008d
kern/debug/kdebug.c:309: print_stackframe+23
ebp: 0x00007b18 eip: 0x0010008d args: 0x00000000 0x00000000 0x00000000 0x00007b88
kern/init/init.c:49: grade_backtrace2+34
ebp: 0x00007b38 eip: 0x001000b6 args: 0x00000000 0x00007b60 0xffff0000 0x00007b64
kern/init/init.c:54: grade_backtrace1+39
ebp: 0x00007b58 eip: 0x001000d4 args: 0x00000000 0xffff0000 0x00007b84 0x00000029
kern/init/init.c:59: grade_backtrace0+24
ebp: 0x00007b78 eip: 0x001000f9 args: 0x00000000 0x00100000 0xffff0000 0x0000001d
kern/init/init.c:64: grade_backtrace+35
ebp: 0x00007b98 eip: 0x00100055 args: 0x001032bc 0x001032a0 0x0000130a 0x00000000
kern/init/init.c:30: kern_init+85
ebp: 0x00007bc8 eip: 0x00007d68 args: 0x00000000 0x00000000 0x00000000 0x00010094
<unknow>: -- 0x00007d68 --
ebp: 0x00007bf8 eip: 0x00007c4f args: 0xc031fcfa 0xc08ed88e 0x64e4d08e 0xfa7502a8
<unknow>: -- 0x00007c4f --
++ setup timer interrupts
我们查看源代码可以发现:
--> kern_init() --> grade_backtrace() --> grade_backtrace0(0, (int)kern_init, 0xffff0000) --> grade_backtrace1(0, 0xffff0000)
--> grade_backtrace2(0,arg1_addr,0xffff0000,arg2_addr) --> mon_backtrace(0, NULL, NULL) --> print_stackframe()
看看输出结果中的参数,发现是正确的。
练习6:完善中断初始化和处理 (需要编程)
void idt_init(void) { /* LAB1 YOUR CODE : STEP 2 */ /* (1) Where are the entry addrs of each Interrupt Service Routine (ISR)? * All ISR's entry addrs are stored in __vectors. where is uintptr_t __vectors[] ? * __vectors[] is in kern/trap/vector.S which is produced by tools/vector.c * (try "make" command in lab1, then you will find vector.S in kern/trap DIR) * You can use "extern uintptr_t __vectors[];" to define this extern variable which will be used later. * (2) Now you should setup the entries of ISR in Interrupt Description Table (IDT). * Can you see idt[256] in this file? Yes, it's IDT! you can use SETGATE macro to setup each item of IDT * (3) After setup the contents of IDT, you will let CPU know where is the IDT by using 'lidt' instruction. * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. * Notice: the argument of lidt is idt_pd. try to find it! */ //galaxy 2014-7-12 int i; extern uintptr_t __vectors[]; for(i=0;i<256;i++){ SETGATE(idt[i],0,8,__vectors[i],0) } lidt(&idt_pd); }
static void trap_dispatch(struct trapframe *tf) { char c; switch (tf->tf_trapno) { case IRQ_OFFSET + IRQ_TIMER: /* LAB1 YOUR CODE : STEP 3 */ /* handle the timer interrupt */ /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks(). * (3) Too Simple? Yes, I think so! */ //galaxy 2014-7-12 ticks++; if(100==ticks) { print_ticks(); ticks=0; } break;


浙公网安备 33010602011771号