小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Linux initrd的分析、創(chuàng)建和使用(轉)接上 - liux系統(tǒng)技術 - 隨心--linux

 黃浦江中的一條魚 2009-07-20
Linux initrd的分析、創(chuàng)建和使用(轉)接上

使用初始 RAM 磁盤來引導系統(tǒng)

現(xiàn)在我們已經(jīng)了解了如何構建并使用定制的初始 RAM 磁盤,本節(jié)將探索內(nèi)核是如何識別 initrd 并將其作為根文件系統(tǒng)進行掛載的。我們將介紹啟動鏈中的幾個主要函數(shù),并解釋一下到底在進行什么操作。

引導加載程序,例如 GRUB,定義了要加載的內(nèi)核,并將這個內(nèi)核映像以及相關的 initrd 拷貝到內(nèi)存中。我們可以在 Linux 內(nèi)核源代碼目錄中的 ./init 子目錄中找到很多這種功能。

在內(nèi)核和 initrd 映像被解壓并拷貝到內(nèi)存中之后,內(nèi)核就會被調(diào)用了。它會執(zhí)行不同的初始化操作,最終您會發(fā)現(xiàn)自己到了 init/main.c:init()(subdir/file:function)函數(shù)中。這個函數(shù)執(zhí)行了大量的子系統(tǒng)初始化操作。此處會執(zhí)行一個對 init/do_mounts.c:prepare_namespace() 的調(diào)用,這個函數(shù)用來準備名稱空間(掛載 dev 文件系統(tǒng)、RAID 或 md、設備以及最后的 initrd)。加載 initrd 是通過調(diào)用 init/do_mounts_initrd.c:initrd_load() 實現(xiàn)的。

initrd_load() 函數(shù)調(diào)用了 init/do_mounts_rd.c:rd_load_image(),它通過調(diào)用 init/do_mounts_rd.c:identify_ramdisk_image() 來確定要加載哪個 RAM 磁盤。這個函數(shù)會檢查映像文件的 magic 號來確定它是 minux、etc2、romfs、cramfs 或 gzip 格式。在返回到 initrd_load_image 之前,它還會調(diào)用 init/do_mounts_rd:crd_load()。這個函數(shù)負責為 RAM 磁盤分配空間,并計算循環(huán)冗余校驗碼(CRC),然后對 RAM 磁盤映像進行解壓,并將其加載到內(nèi)存中?,F(xiàn)在,我們在一個適合掛載的塊設備中就有了這個 initrd 映像。

現(xiàn)在使用一個 init/do_mounts.c:mount_root() 調(diào)用將這個塊設備掛載到根文件系統(tǒng)上。它會創(chuàng)建根設備,并調(diào)用 init/do_mounts.c:mount_block_root()。在這里調(diào)用 init/do_mounts.c:do_mount_root(),后者又會調(diào)用 fs/namespace.c:sys_mount() 來真正掛載根文件系統(tǒng),然后 chdir 到這個文件系統(tǒng)中。這就是我們在清單 6 中所看到的熟悉消息 VFS: Mounted root (ext2 file system). 的地方。

最后,返回到 init 函數(shù)中,并調(diào)用 init/main.c:run_init_process。這會導致調(diào)用 execve 來啟動 init 進程(在本例中是 /linuxrc)。linuxrc 可以是一個可執(zhí)行程序,也可以是一個腳本(條件是它有腳本解釋器可用)。

這些函數(shù)的調(diào)用層次結構如清單 7 所示。盡管此處并沒有列出拷貝和掛載初始 RAM 磁盤所涉及的所有函數(shù),但是這足以為我們提供一個整體流程的粗略框架。


清單 7. initrd 加載和掛載過程中所使用的主要函數(shù)的層次結構
init/main.c:init
                        init/do_mounts.c:prepare_namespace
                        init/do_mounts_initrd.c:initrd_load
                        init/do_mounts_rd.c:rd_load_image
                        init/do_mounts_rd.c:identify_ramdisk_image
                        init/do_mounts_rd.c:crd_load
                        lib/inflate.c:gunzip
                        init/do_mounts.c:mount_root
                        init/do_mounts.c:mount_block_root
                        init/do_mounts.c:do_mount_root
                        fs/namespace.c:sys_mount
                        init/main.c:run_init_process
                        execve

無盤引導

與嵌入式引導的情況類似,本地磁盤(軟盤或 CD-ROM)對于引導內(nèi)核和 ramdisk 根文件系統(tǒng)來說都不是必需的。DHCP(Dynamic Host Configuration Protocol)可以用來確定網(wǎng)絡參數(shù),例如 IP 地址和子網(wǎng)掩碼。TFTP(Trivial File Transfer Protocol)可以用來將內(nèi)核映像和初始 ramdisk 映像傳輸?shù)奖镜卦O備上。傳輸完成之后,就可以引導 Linux 內(nèi)核并掛載 initrd 了,這與本地映像引導的過程類似。

壓縮 initrd

在構建嵌入式系統(tǒng)時,我們可能希望將 initrd 映像文件做得盡可能小,這其中有一些技巧需要考慮。首先是使用 BusyBox(本文中已經(jīng)展示過了)。BusyBox 可以將數(shù) MB 的工具壓縮成幾百 KB。

在這個例子中,BusyBox 映像是靜態(tài)鏈接的,因此它不需要其他庫。然而,如果我們需要標準的 C 庫(我們自己定制的二進制可能需要這個庫),除了巨大的 glibc 之外,我們還有其他選擇。第一個較小的庫是 uClibc,這是為對空間要求非常嚴格的系統(tǒng)準備的一個標準 C 庫。另外一個適合空間緊張的環(huán)境的庫是 dietlib。要記住我們需要使用這些庫來重新編譯想在嵌入式系統(tǒng)中重新編譯的二進制文件,因此這需要額外再做一些工作(但是這是非常值得的)。

結束語

初始 RAM 磁盤最初是設計用來通過一個臨時根文件系統(tǒng)來作為內(nèi)核到最終的根文件系統(tǒng)之間的橋梁。initrd 對于在嵌入式系統(tǒng)中加載到 RAM 磁盤里的非持久性根文件系統(tǒng)來說也非常有用。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多