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