MIT 6.828 JOS學習筆記4. Lab 1 Part 2.1: The Boot Loader


Part 2: The Boot Loader

對於PC來說,軟盤,硬盤都可以被划分為一個個大小為512字節的區域,叫做扇區。一個扇區是一次磁盤操作的最小粒度。每一次讀取或者寫入操作都必須是一個或多個扇區。如果一個磁盤是可以被用來啟動操作系統的,就把這個磁盤的第一個扇區叫做啟動扇區。這一部分介紹的boot loader程序就位於這個啟動扇區之中。當BIOS找到一個可以啟動的軟盤或硬盤后,它就會把這512字節的啟動扇區加載到內存地址0x7c00~0x7dff這個區域內。

對於6.828,我們將采用傳統的硬盤啟動機制,這就意味着我們的boot loader程序的大小必須小於512字節。整個boot loader是由一個匯編文件,boot/boot.S,以及一個C語言文件,boot/main.c。Boot loader必須完成兩個主要的功能。

 1. 首先,boot loader要把處理器從實模式轉換為32bit的保護模式,因為只有在這種模式下軟件可以訪問超過1MB空間的內容。

 2. 然后,boot loader可以通過使用x86的特定的IO指令,直接訪問IDE磁盤設備寄存器,從磁盤中讀取內核。

對於boot loader來說,有一個文件很重要,obj/boot/boot.asm。這個文件是我們真實運行的boot loader程序的反匯編版本。所以我們可以把它和它的源代碼即boot.S以及main.c比較一下。

Exercise 3:

設置一個斷點在地址0x7c00處,這是boot sector被加載的位置。然后讓程序繼續運行直到這個斷點。跟蹤/boot/boot.S文件的每一條指令,同時使用boot.S文件和系統為你反匯編出來的文件obj/boot/boot.asm。你也可以使用GDB的x/i指令來獲取去任意一個機器指令的反匯編指令,把源文件boot.S文件和boot.asm文件以及在GDB反匯編出來的指令進行比較。

追蹤到bootmain函數中,而且還要具體追蹤到readsect()子函數里面。找出和readsect()c語言程序的每一條語句所對應的匯編指令,回到bootmain(),然后找出把內核文件從磁盤讀取到內存的那個for循環所對應的匯編語句。找出當循環結束后會執行哪條語句,在那里設置斷點,繼續運行到斷點,然后運行完所有的剩下的語句。

這道題的解答在這篇日志中:

  http://www.cnblogs.com/fatsheep9146/p/5115086.html 
 
下面回答一下文中提出的四個問題:
  1. 在什么時候處理器開始運行於32bit模式?到底是什么把CPU從16位切換為32位工作模式?
 答:在boot.S文件中,計算機首先工作於實模式,此時是16bit工作模式。當運行完 " ljmp $PROT_MODE_CSEG, $protcseg " 語句后,正式進入32位工作模式。根本原因是此時CPU工作在保護模式下。
 
  2. boot loader中執行的最后一條語句是什么?內核被加載到內存后執行的第一條語句又是什么?
 答:boot loader執行的最后一條語句是bootmain子程序中的最后一條語句 " ((void (*)(void)) (ELFHDR->e_entry))(); ",即跳轉到操作系統內核程序的起始指令處。
     這個第一條指令位於/kern/entry.S文件中,第一句 movw $0x1234, 0x472
  
   3. 內核的第一條指令在哪里?
 答:上一個問題中已經回答過這個問題,第一條指令位於/kern/entry.S文件中。
 
  4. boot loader是如何知道它要讀取多少個扇區才能把整個內核都送入內存的呢?在哪里找到這些信息?
 答:首先關於操作系統一共有多少個段,每個段又有多少個扇區的信息位於操作系統文件中的Program Header Table中。這個表中的每個表項分別對應操作系統的一個段。並且每個表項的內容包括這個段的大小,段起始地址偏移等等信息。所以如果我們能夠找到這個表,那么就能夠通過表項所提供的信息來確定內核占用多少個扇區。
   那么關於這個表存放在哪里的信息,則是存放在操作系統內核映像文件的ELF頭部信息中。
 
 
 下一篇博文中我們繼續~
 
 歡迎大家的意見與指導~
   zzqwf12345@163.com
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM