GRUB是目前較流行啟動引導程序。其第二版被主流linux發行版所包括。本文將探索和分析GRUB的設計和實現機制。
boot.S是第一個研究對象,因為boot.S將被編譯成boot.img(512字節),安裝時安裝在0號扇區,即主引導扇區(MBR)。
BIOS引導時會把主引導扇區裝載到0x7c00開始的512字節內存區域,并設置CS:ip為0x0000:7c00。接著CPU會執行0x7c00處的指令,即boot.img(boot.S)中的第一條指令: jmp LOCAL(after_BPB) /* 機器碼: eb 63 */ ,跳轉到偏移量0x65的地方。
接下去的代碼檢查并設置正確的引導驅動器號碼。
設置實模式堆棧指針為0x2000。
打印提示信息,如果沒按SHIFT鍵并且不是SILENT引導的話。
調用BIOS中斷INT 0x13, AH 0x41檢測BIOS是否支持磁盤LBA模式。
如果支持LBA模式,通過BIOS中斷INT 0x13, AH 0x42來裝載1號扇區到地址0x70000(0x7000:0000)開始的內存區域。
如果不支持LBA模式,就使用CHS模式。通過BIOS中斷INT 0x13, AH 0x02裝載1號扇區到地址0x70000(0x7000:0000)開始的內存區域。這里會先調用BIOS中斷INT 0x13, AH 0x13來獲取磁盤參數。如果失敗了并且啟動盤是軟盤的話,會進行軟盤探測。有意思的是軟盤探測的代碼是放在偏移量0x1be開始的區域內的,也就是硬盤分區表在MBR中的相應位置。因為軟盤是不使用硬盤分區表的,所以覆蓋沒有關系。而當boot.img被安裝到硬盤上時,安裝時這段代碼將不會被復制,因為硬盤引導不需要進行軟盤探測,失敗就失敗了。
接下來跳轉到被命名為copy_buffer的一段代碼來將前面裝載到地址0x70000的1號扇區數據復制到內存地址0x8000開始的內存區域。
最后,在偏移量0x016f處執行指令 jmp *(kernel_address) /* 機器碼: ff 26 5a 7c */ 會跳轉到0x8000執行下一條指令。
至此boot.S中的代碼執行完畢。
下一篇
新聞熱點
疑難解答