Linux 如何載入“initrd”映像?
我一直在試圖了解引導過程,但只有一件事讓我頭疼..
一旦 Linux 核心啟動並掛載了根文件系統 (/),就可以執行程序並集成更多核心模組以提供附加功能。要掛載根文件系統,必須滿足某些條件。核心需要相應的驅動程序才能訪問根文件系統所在的設備(尤其是SCSI驅動程序)。核心還必須包含讀取文件系統所需的程式碼(ext2、reiserfs、romfs 等)。也可以想像,根文件系統已經被加密了。在這種情況下,安裝文件系統需要密碼。
初始 ramdisk(也稱為 initdisk 或 initrd)正好解決了上述問題。Linux 核心提供了一個選項,即在安裝實際的根文件系統之前將一個小文件系統載入到 RAM 磁碟並在其中執行程序。**initrd 的載入由引導載入程序(GRUB、LILO 等)處理。引導載入程序只需要 BIOS 常式即可從引導介質載入數據。**如果引導載入程序能夠載入核心,它也可以載入初始 ramdisk。不需要特殊的驅動程序。
如果 /boot 不是不同的分區,但存在於 / 分區中,那麼引導載入程序不應該需要 SCSI 驅動程序來訪問“initrd”映像和核心映像嗎?如果您可以直接訪問圖像,那麼我們究竟為什麼需要 SCSI 驅動程序?
鄰居,我將嘗試回答您的問題,但要更全面地描述引導過程,請嘗試IBM 的這篇文章。
好的,我假設您使用 GRUB 或 GRUB2 作為引導載入程序來進行解釋。首先,當 BIOS 訪問您的磁碟以載入引導載入程序時,它會利用其內置常式進行磁碟訪問,這些常式儲存在著名的 13h 中斷中。引導載入程序(和設置階段的核心)在訪問磁碟時會使用這些常式。請注意,BIOS 在處理器的實模式(16 位模式)下執行,因此它不能定址超過 2^20 字節的 RAM(2^20,而不是 2^16,因為實模式中的每個地址都由 segment_address* 16 + 偏移量,其中段地址和偏移量都是 16 位,請參閱Wikipedia 上的“x86 記憶體分段”)。因此,這些常式不能訪問超過 1 MiB 的 RAM,這是一個嚴格的限制和主要的不便之處。
BIOS 直接從 MBR(磁碟的前 512 個字節)載入引導載入程式碼並執行它。如果您使用的是 GRUB,則該程式碼是 GRUB 階段 1。該程式碼載入 GRUB 階段 1.5,它位於磁碟空間的前 32 KiB 中,稱為 DOS 兼容區域,或者來自文件系統的固定地址。這樣做不需要了解文件系統結構,因為即使 stage 1.5 在文件系統中,它也是“原始”程式碼,可以直接載入到 RAM 並執行:參見 “PC 上 GRUB 的詳細資訊” ” 在 pixelbeat.org,這是下圖的來源。階段 1.5 從磁碟載入到 RAM 使用 BIOS 磁碟訪問常式。
階段 1.5 包含文件系統實用程序,因此它可以從文件系統讀取階段 2(好吧,它仍然使用 BIOS 13h 從磁碟讀取到 RAM,但現在它可以破譯有關 inode 等的文件系統資訊,並獲取原始程式碼出磁碟)。由於磁碟定址模式的限制,較舊的 BIOS 可能無法訪問整個 HD - 它們可能使用 Cylinder-Head-Sector 系統,無法定址超過前 8 GiB 的磁碟空間:http://en.wikipedia。 org/wiki/氣缸蓋扇區。
第 2 階段將核心載入到 RAM 中(同樣,使用 BIOS 磁碟實用程序)。如果是 2.6+ 核心,它還編譯了 initramfs,所以不需要載入它。如果是較舊的核心,引導載入程序還將獨立的 initrd 映像載入到記憶體中,以便核心可以掛載它並從磁碟獲取用於掛載真實文件系統的驅動程序。
問題是核心(和 ramdisk)的重量超過 1 MiB;因此,要將它們載入到 RAM 中,您必須將核心載入到前 1 MiB,然後跳轉到保護模式(32 位),將載入的核心移動到高記憶體(釋放前 1 MiB 用於實模式),然後返回再次進入真實(16 位)模式,從磁碟獲取 ramdisk 到第一個 1 MiB(如果它是單獨的 initrd 和較舊的核心),可能再次切換到受保護(32 位)模式,將其放在它所屬的位置,可能得到返回實模式(或不:https://stackoverflow.com/questions/4821911/does-grub-switch-to-protected-mode)並執行核心程式碼。警告:我不完全確定這部分描述的徹底性和準確性。
現在,當您最終執行核心時,您已經將它和 ramdisk 通過 bootloader 載入到 RAM 中,因此核心可以使用 ramdisk 中的磁碟實用程序來掛載您真正的根文件系統並將根轉向它。ramfs 驅動程序存在於核心中,因此它當然可以理解 initramfs 的內容。