天天看點

MIT OS 5. 小結@ Lab1

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;

        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 }