Linux從開機到登錄啟動過程綜述
Bootloader
在Alpha/AXP平臺上引導Linux通常有兩種方法,一種是由MILO及其他類似的引導程序引導,另一種是由Firmware直接引導。MILO功能與i386平臺的LILO相近,但內(nèi)置有基本的磁盤驅(qū)動程序(如IDE、SCSI等),以及常見的文件系統(tǒng)驅(qū)動程序(如ext2,iso9660等), firmware有ARC、SRM兩種形式,ARC具有類BIOS界面,甚至還有多重引導的設(shè)置;而SRM則具有功能強大的命令行界面,用戶可以在控制臺上使用boot等命令引導系統(tǒng)。ARC有分區(qū)(Partition)的概念,因此可以訪問到分區(qū)的首扇區(qū);而SRM只能將控制轉(zhuǎn)給磁盤的首扇區(qū)。兩種firmware都可以通過引導MILO來引導Linux,也可以直接引導Linux的引導代碼。
“arch/alpha/boot”下就是制作Linux Bootloader的文件。“head.S”文件提供了對 OSF PAL/1的調(diào)用入口,它將被編譯后置于引導扇區(qū)(ARC的分區(qū)首扇區(qū)或SRM的磁盤0扇區(qū)),得到控制后初始化一些數(shù)據(jù)結(jié)構(gòu),再將控制轉(zhuǎn)給“main.c”中的start_kernel(), start_kernel()向控制臺輸出一些提示,調(diào)用pal_init()初始化PAL代碼,調(diào)用openboot() 打開引導設(shè)備(通過讀取Firmware環(huán)境),調(diào)用load()將核心代碼加載到START_ADDR(見 “include/asm-alpha/system.h”),再將Firmware中的核心引導參數(shù)加載到ZERO_PAGE(0) 中,最后調(diào)用runkernel()將控制轉(zhuǎn)給0x100000的kernel,bootloader部分結(jié)束。
Bootloader中使用的所有“srm_”函數(shù)在“arch/alpha/lib/”中定義。
以上這種Boot方式是一種最簡單的方式,即不需其他工具就能引導Kernel,前提是按照 Makefile的指導,生成bootimage文件,內(nèi)含以上提到的bootloader以及vmlinux,然后將 bootimage寫入自磁盤引導扇區(qū)始的位置中。
當采用MILO這樣的引導程序來引導Linux時,不需要上面所說的Bootloader,而只需要 vmlinux或vmlinux.gz,引導程序會主動解壓加載內(nèi)核到0x1000(小內(nèi)核)或0x100000(大內(nèi)核),并直接進入內(nèi)核引導部分,即本文的第二節(jié)。
對于I386平臺
i386系統(tǒng)中一般都有BIOS做最初的引導工作,那就是將四個主分區(qū)表中的第一個可引導分區(qū)的第一個扇區(qū)加載到實模式地址0x7c00上,然后將控制轉(zhuǎn)交給它。
在“arch/i386/boot”目錄下,bootsect.S是生成引導扇區(qū)的匯編源碼,它首先將自己拷貝到0x90000上,然后將緊接其后的setup部分(第二扇區(qū))拷貝到0x90200,將真正的內(nèi)核代碼拷貝到0x100000。以上這些拷貝動作都是以bootsect.S、setup.S以及vmlinux在磁盤上連續(xù)存放為前提的,也就是說,我們的bzImage文件或者zImage文件是按照bootsect,setup, vmlinux這樣的順序組織,并存放于始于引導分區(qū)的首扇區(qū)的連續(xù)磁盤扇區(qū)之中。
bootsect.S完成加載動作后,就直接跳轉(zhuǎn)到0x90200,這里正是setup.S的程序入口。 setup.S的主要功能就是將系統(tǒng)參數(shù)(包括內(nèi)存、磁盤等,由BIOS返回)拷貝到 0x90000-0x901FF內(nèi)存中,這個地方正是bootsect.S存放的地方,這時它將被系統(tǒng)參數(shù)覆蓋。以后這些參數(shù)將由保護模式下的代碼來讀取。
除此之外,setup.S還將video.S中的代碼包含進來,檢測和設(shè)置顯示器和顯示模式。最后,setup.S將系統(tǒng)轉(zhuǎn)換到保護模式,并跳轉(zhuǎn)到0x100000(對于bzImage格式的大內(nèi)核是 0x100000,對于zImage格式的是0x1000)的內(nèi)核引導代碼,Bootloader過程結(jié)束。
對于2.4.x版內(nèi)核
沒有什么變化。
Kernel引導入口
對于I386平臺
在i386體系結(jié)構(gòu)中,因為i386本身的問題,在"arch/alpha/kernel/head.S"中需要更多的設(shè)置,但最終也是通過call SYMBOL_NAME(start_kernel)轉(zhuǎn)到start_kernel()這個體系結(jié)構(gòu)無關(guān)的函數(shù)中去執(zhí)行了。
所不同的是,在i386系統(tǒng)中,當內(nèi)核以bzImage的形式壓縮,即大內(nèi)核方式(__BIG_KERNEL__)壓縮時就需要預先處理bootsect.S和setup.S,按照大核模式使用$(CPP) 處理生成bbootsect.S和bsetup.S,然后再編譯生成相應的.o文件,并使用 "arch/i386/boot/compressed/build.c"生成的build工具,將實際的內(nèi)核(未壓縮的,含 kernel中的head.S代碼)與"arch/i386/boot/compressed"下的head.S和misc.c合成到一起,其中的head.S代替了"arch/i386/kernel/head.S"的位置,由Bootloader引導執(zhí)行(startup_32入口),然后它調(diào)用misc.c中定義的decompress_kernel()函數(shù),使用 "lib/inflate.c"中定義的gunzip()將內(nèi)核解壓到0x100000,再轉(zhuǎn)到其上執(zhí)行 "arch/i386/kernel/head.S"中的startup_32代碼。
新文章:
- CentOS7下圖形配置網(wǎng)絡(luò)的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統(tǒng)后丟失windows啟動項
- CentOS單網(wǎng)卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網(wǎng)打印機IP講解
- CentOS7使用hostapd實現(xiàn)無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網(wǎng)絡(luò)重啟出錯
- 解決Centos7雙系統(tǒng)后丟失windows啟動項
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統(tǒng)有什么不同呢
- Centos 6.6默認iptable規(guī)則詳解