1.PC机的复位地址:[F000:FFF0] 位于BISO代码快。
2.BISO之后第一条指令地址:[0000:7c00],位于内存中。BISO事先将MBR复制到此处。
3.printf.c / console.c
console.c里面负责初始化显示器(CGA/VGA),串口(UART),并口(Parallel).并实现了getchar和putchar函数。getchar以中断方式从uart中获得一个字符;putchar将一个字符同时打印到显示器,串口和并口上。
printf.c里面是格式化输出的函数,对于格式化字符串通过vprintfmt(不定参数个数)调用来确定要打印的字符串序列,最终都是通过putchar函数打印。
4.crt_pos表示当前光标的位置,而CRT_SIZE定义了整个屏幕的大小:
#define CRT_SIZE (CRT_ROWS * CRT_COLS)
当光标超出当前屏幕的时候就需要滚屏了,就是屏幕往上翻。这里一般向上滚动一行。
5.有关va_list以及相关的宏操作,参见:http://blog.csdn.net/yunhuang2010/article/details/8473279
va_list主要是利用X86里面函数参数用栈传递的特点。
6.X86系统调用函数必须先准备一定的环境。主要是通过压栈实现,先压函数参数,再压函数返回地址(一般是由call指令实现),母函数的EBP返回值(一般在子函数的最开始压栈)。(EBP--->ESP之间是当前活动栈的范围,把母函数的栈底保存,同时将更新栈底成当前栈顶,开启新的活动栈。这时的栈顶其实保存的老栈底。
7.kdebug:
Eipdebuginfo:
info->eip_file = "<unknown>";
info->eip_line = 0;
info->eip_fn_name = "<unknown>";
info->eip_fn_namelen = 9;
info->eip_fn_addr = addr;
kern/kern/monitor.c:27:
63:
2.BISO之后第一条指令地址:[0000:7c00],位于内存中。BISO事先将MBR复制到此处。
3.printf.c / console.c
console.c里面负责初始化显示器(CGA/VGA),串口(UART),并口(Parallel).并实现了getchar和putchar函数。getchar以中断方式从uart中获得一个字符;putchar将一个字符同时打印到显示器,串口和并口上。
printf.c里面是格式化输出的函数,对于格式化字符串通过vprintfmt(不定参数个数)调用来确定要打印的字符串序列,最终都是通过putchar函数打印。
4.crt_pos表示当前光标的位置,而CRT_SIZE定义了整个屏幕的大小:
#define CRT_SIZE (CRT_ROWS * CRT_COLS)
当光标超出当前屏幕的时候就需要滚屏了,就是屏幕往上翻。这里一般向上滚动一行。
5.有关va_list以及相关的宏操作,参见:http://blog.csdn.net/yunhuang2010/article/details/8473279
va_list主要是利用X86里面函数参数用栈传递的特点。
6.X86系统调用函数必须先准备一定的环境。主要是通过压栈实现,先压函数参数,再压函数返回地址(一般是由call指令实现),母函数的EBP返回值(一般在子函数的最开始压栈)。(EBP--->ESP之间是当前活动栈的范围,把母函数的栈底保存,同时将更新栈底成当前栈顶,开启新的活动栈。这时的栈顶其实保存的老栈底。
7.kdebug:
Eipdebuginfo:
info->eip_file = "<unknown>";
info->eip_line = 0;
info->eip_fn_name = "<unknown>";
info->eip_fn_namelen = 9;
info->eip_fn_addr = addr;
info->eip_fn_narg = 0;
kern/kdebug.c:182:
// Your code here.
182 stab_binsearch(stabs, &lline, &rline, N_SLINE, addr);
183 if(lline >= 0 && lline <= rline)
184 {
185 info->eip_line = rline;
186 //if(rline==lline) cprintf("info");
187 }
188 else return -1;
189
kern/kern/monitor.c:27:
24 static struct Command commands[] = {
25 { "help", "Display this list of commands", mon_help },
26 { "kerninfo", "Display information about the kernel", mon_kerninfo },
27
28 { "trace", "trace back to upper functions", mon_backtrace },
29 };
63:
62 int
63 mon_backtrace(int argc, char **argv, struct Trapframe *tf)
64 {
65 // Your code here.
66 uint32_t ebp, * pointer;
67 uint32_t addr;
68 struct Eipdebuginfo info;
69 ebp = read_ebp();
70 while(ebp != 0x00)
71 {
72 pointer = (uint32_t *) ebp;
73 addr = *(pointer+1);
74 cprintf("ebp %08x eip %08x args %08x %08x %08x %08x %08x\r\n", \
75 ebp,addr,*(pointer+2),*(pointer+3),*(pointer+4),*(pointer+5),*(pointer+6));
76 debuginfo_eip(addr,&info);
77 cprintf("\t%s:%d: %.*s+%d\r\n",info.eip_file,info.eip_line, \
78 info.eip_fn_namelen,info.eip_fn_name,addr - info.eip_fn_addr);
79 ebp = *pointer;
80 }
81 return 0;
82 }