x86下SylixOS引導過程分析
當x86電源打開後,CPU將自動進入實模式,並從地址0xFFFF0(CS:0xFFFF,IP:0x0)開始自動運行程序代碼,此地址一般是BIOS的地址。
BIOS啟動後,將啟動設備的主引導記錄。主引導記錄位於第0磁道的第1個扇區,它的大小是512字節,裏面存放了用匯編語言編寫的預啟動信息、分區表信息、魔數0x55AA等。
BIOS將主引導記錄讀入內存絕對地址0x7C00處,並跳轉到此地址運行。
在SylixOS平臺中,事實上被拷貝到物理內存0x7C00處的內容就是GRUB。
2. GRUB的作用
GRUB是目前較流行啟動引導程序。
GRUB(Grand Unified Bootloader)是當前Linux諸多發行版本默認的引導程序,SylixOS遵循了GRUB的引導協議Multiboot後,也可以使用GRUB進行引導。
GRUB分為1.x版本和2.x版本,兩個版本的架構有所不同,目前SylixOS啟動還是使用1.x版本的GRUB。
GRUB1.x磁盤引導SylixOS全過程:
- stage1
GRUB讀取磁盤的第一個512字節的主引導記錄MBR。 - stage1.5
識別各種不同的文件系統格式,目的是為了GRUB能識別到文件系統。 - stage2
載入系統引導菜單(“/boot/grub/menu.lst”或“grub.lst”),載入SylixOS的x86鏡像bspx86.elf。3. Multiboot協議
為了統一x86平臺GRUB引導各式操作系統的流程,GRUB支持了Multiboot的引導協議,該協議定義了一個可識別的系統鏡像文件頭部應具備的格式協議,Multiboot首部定義如下表所示。
Offset | Type Field | Name | Note |
---|---|---|---|
0 | u32 | magic | required |
4 | u32 | flags | required |
8 | u32 | checksum | required |
12 | u32 | header_addr | if flags[16] is set |
16 | u32 | load_addr | if flags[16] is set |
20 | u32 | load_end_addr | if flags[16] is set |
24 | u32 | bss_end_addr | if flags[16] is set |
28 | u32 | entry_addr | if flags[16] is set |
32 | u32 | mode_type | if flags[02] is set |
36 | u32 | width | if flags[02] is set |
40 | u32 | height | if flags[02] is set |
44 | u32 | depth | if flags[02] is set |
SylixOS參照上表所示的Multiboot首部定義規則,對SylixOS的x86鏡像的Multiboot首部進行了定義,如下圖所示。
並且按照Multiboot的協議要求,Multiboot的首部應當位於整個elf鏡像的首部位置,所以對於SylixOS的BSP鏡像工程,在鏈接Multiboot文件時需要指定其地址,如下圖所示。
4. SylixOS啟動
4.1 GRUB解析bspx86.elf
GRUB啟動時,會根據menu.lst文件加載對應的系統鏡像。
SylixOS的RealEvo-IDE默認提供的menu.lst文件內容如下圖所示。
在menu.lst文件中指定了GRUB啟動的默認等待時間timeout、默認加載菜單項default以及各菜單條目。
如,菜單條目“title SylixOS(UP)”,其定義了使用GRUB的kernel命令引導bspx86.elf文件,並為其傳遞“ncpus=1 hz=1000”等參數。
GRUB的kernel命令會解析bspx86.elf文件,判斷其Multiboot首部的有效性,在有效性完整判斷結束之後,根據elf的頭信息,對bspx86.elf的各個段進行重定位。
4.2 重定位入口地址
elf文件的頭信息中包含了該elf文件眾多的信息,使用elf文件分析工具等程序,可以查看elf文件頭部的信息,如下圖所示。
程序的入口地址是在elf文件中設定好的,所以GRUB在將SylixOS鏡像重定位後,也會將該入口地址設置在elf頭信息中指定的位置。
4.3 跳轉到主核入口地址
x86主核入口代碼如下圖所示。
以SylixOS的32位系統為例,在跳轉到該入口地址後,應先設置棧指針,而設置棧指針之前,需要關閉中斷。
最後調用CALL命令,跳轉到C程序入口bspInit,而bspInit的兩個參數由%EBX和%EAX寄存器傳遞,分別為Multiboot的魔數和Multiboot信息結構體的首地址。
4.4 主核引導從核啟動
主核引導從核啟動也是遵循了Intel制定的從核啟動規則。
如下圖所示,BSP為BIOS引導的主核,AP為待BSP啟動的從核。BSP需要首先向AP發送INIT IPI命令,之後連續發送兩次STARTUP IPI命令。
INIT IPI命令與STARTUP IPI命令都是固定的帶有參數的指令,通過核間中斷的方式進行發送。
INIT IPI命令可以使AP自動進行復位操作,並完成上電啟動後POST自檢等硬件所需流程。
STARTUP IPI命令中可以指定從核跳轉到實模式執行的指令內容和地址,由此可以使從核按照SMP或AMP的流程進行初始化。
x86下SylixOS引導過程分析