以32位x86,bzImge爲例
grub版本爲0.97
1、計算機上電
2、0xFFFFFFF0
當cpu檢測reset引腳上的信號後
便將指令指針寄存器的值設置爲0xfff0
——INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986, Chapter 10
此時爲實模式,cpu將執行物理地址0xFFFFFFF0處的指令
訪址的時候,硬件將該地址映射到BIOS的ROM中
BIOS中的指令將MBR複製到物理地址0x7c00處,並跳轉到該處執行
3、0x7C00
MBR中的指令由grub安裝而來,爲grub-0.97/stage1/stage1.S
stage1將stage2的第1部分grub-0.97/stage2/start.S(512字節)複製到物理地址0x8000處,並跳轉到該處執行
stage2將剩餘部分grub-0.97/stage2/asm.S複製到物理地址0x8200處,並跳轉到該處執行
...
grub-0.97/stage2/boot.c——load_image()函數
將內核映像bzImage的setup部分複製到物理地址0x90000
vmlinux部分複製到物理地址0x100000處
隨後跳轉到0x90200處執行
4、0x90200
arch/x86/boot/heaer.S——_start => start_of_setup
檢查準備實模式堆棧,bss段清0,隨後調用arch/x86/boot/main.c——main()函數
main()中使用BIOS中斷讀取一些硬件信息,如內存信息等
最後調用arch/x86/boot/pm.c——go_to_protected_mode()函數
go_to_protected_mode()設置段描述符,隨後調用arch/x86/boot/pmjump.S——protected_mode_jump()函數
protected_mode_jump()置cr0的PE位,開啓保護模式
最後跳轉到code32_start,對於bzImage即物理地址0x100000,grub複製的bzImage第2部分
5、0x100000
arch/x86/boot/compressed/head_32.S——startup_32
arch/x86/boot/compressed/misc.c——decompress_kernel()解壓內核
解壓完成後跳轉到output
6、LOAD_PHYSICAL_ADDR
根據不同的配置,解壓後的代碼在物理內存中的起始位置亦不同
arch/x86/kernel/head_32.S——startup_32
設置頁表,置cr0的PG位,開啓分頁
最後跳轉到arch/x86/kernel/head32.c——i386_start_kernel()函數
i386_start_kernel()中最後調用start_kernel()
7、start_kernel()
init/main.c——start_kernel()
進入c代碼部分
詳細的註釋請參考git://github.com/kernel-digger/linux-2.6.git
錯漏之處還望不吝指出