2021-05-12 14:32:11
淺析 GRUB 如何載入 Linux kernel
前言
對於 GRUB 的載入流程,網上絕大部分都是寫對 menu.lst, grub.cfg 這些 GRUB 組態檔的編寫流程,就像是寫指令碼語言一樣,用些關鍵字就能讓 PC機能正確啟動桌面 Linux 了。但這只是 GRUB 的使用,而不是GRUB的分析。
本來是沒有想要探究 GRUB 的想法,直到我在自製toy kernel 的學習中進入了 “虛擬記憶體管理”這一章節。很多介紹虛擬記憶體管理的時候都會說到 Linux 的記憶體管理,Linux 核心會載入到系統 3G~4G 的虛擬記憶體中, 但 GRUB 是沒有開啟虛擬記憶體的,Linux 核心的載入是被誰,又是如何載入相應段到 3G~4G 區的呢。
分析 kernel
vmLinux
我們看下核心原始碼編譯後的最原始檔案 vmLinux。該檔案是 ELF 檔案,使用 readelf 讀下該檔案的 Section header.
這裡只截了幾個段顯示,後面的段都類似. 可以看到這些需要載入的段的地址的確是在 0xC0000000 之後。但 vmLinux 並不是可引導的Linux 核心檔案。
Linux啟動的相關資訊一般都在 `/boot` 下,我們看下裡面的內容.
可以看到 grub 資料夾,grub 就是引導 Linux 進行啟動的 bootloader,我們看下 `/boot/grub/grub.cfg` 檔案的內容。
menuentry 'Linux Mint 17 {
recordfail
gfxmode $linux_gfx_mode
insmod gzio
insmod part_msdos
insmod ext2
set root='hd0,msdos1'
linux /boot/vmlinuz-3.13.0-24-generic
initrd /boot/initrd.img-3.13.0-24-generic
}
帶有 linux 的一行就指定了啟動的核心,可以看到不是 vmlinux 檔案,而是 vmlinuz 檔案。
vmlinuz
搜尋後可以看到 vmlinuz 是**可引導的,壓縮**的核心。 initrd 是"initial ramdisk" 的簡寫,是臨時的虛擬磁碟,暫時不討論。 因為我電腦上 vmlinuz 是64 bit的,對 64bit不太了解,所以找了個 32bit 的vmlinuz 檔案來作解析。先試試`readelf`命令。
# readelf -S vmlinuz
readelf:錯誤: Unable to read in 0x7269 bytes of 節頭
readelf:錯誤: 不是 ELF 檔案 - 它開頭的 magic 位元組錯誤
不是 ELF 檔案, 那試試 `objdump` 吧。
# objdump -afh vmlinuz
objdump: vmlinuz: 不可識別的檔案格式
還是不行。
這個時候之所以會相當用這些命令看 vmlinuz 檔案的段資訊,因為在我的 toy kernel 中使用的是 ELF 檔案,而且是使用 grub 載入的,對於 ELF 檔案來說內部保護若干 section, 執行時這些 section 必須要在特地的記憶體地址上. 使用 `readelf` 檢視toy kernel 的 section header 資訊如下.
可以看到 Addr 段就是核心執行時這些段在記憶體中的地址。而載入我的核心的 grub 的設定如下
title toy kernel
root (fd0)
kernel /zkernel
module /initrd
vmlinuz 之所以叫做壓縮的核心,是因為它是使用 gzip 壓縮後得來,而且不單單是個純封包,在檔案開頭部分內嵌有 gzip 解壓縮程式碼,相當於"自解壓"。我的核心需要由grub載入好相應的 section, 但 vmlinuz 都讀不出來段如何讓 grub 載入?
其實答案就在上面的 grub 組態檔裡,在 linux 中宣告核心使用的是 *linux* 關鍵字,在我的設定中宣告核心使用的卻是 *kernel*. 可以明確看出,grub對 linux 的載入是特殊對待的, 但具體怎麼特使對待,只能從原始碼裡看了。
如何在Ubuntu12.04/12.10中重灌或修復Grub2引導 http://www.linuxidc.com/Linux/2012-11/74901.htm
Linux啟動引導過程 grub和mbr http://www.linuxidc.com/Linux/2013-07/87923.htm
grub 的安裝與使用 http://www.linuxidc.com/Linux/2013-07/87682.htm
grub載入程式組態檔分析 http://www.linuxidc.com/Linux/2013-07/87547.htm
CentOS 6.4 grub加密碼 http://www.linuxidc.com/Linux/2013-07/87124.htm
CentOS GRUB引導錯誤無法進入系統解決辦法 http://www.linuxidc.com/Linux/2014-11/108835.htm
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2015-02/113021p2.htm
相關文章