Linux內核加載過程

以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

錯漏之處還望不吝指出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章