Linux? 初始 RAM 磁盤(pán)(initrd)是在系統(tǒng)引導(dǎo)過(guò)程中掛載的一個(gè)臨時(shí)根文件系統(tǒng),用來(lái)支持兩階段的引導(dǎo)過(guò)程。initrd 文件中包含了各種可執(zhí)行程序和驅(qū)動(dòng)程序,它們可以用來(lái)掛載實(shí)際的根文件系統(tǒng),然后再將這個(gè) initrd RAM 磁盤(pán)卸載,并釋放內(nèi)存。在很多嵌入式 Linux 系統(tǒng)中,initrd 就是最終的根文件系統(tǒng)。本文將探索 Linux 2.6 的初始 RAM 磁盤(pán),包括如何創(chuàng)建以及如何在 Linux 內(nèi)核中使用。
什么是初始 RAM 磁盤(pán)?
初始 RAM 磁盤(pán)(initrd)是在實(shí)際根文件系統(tǒng)可用之前掛載到系統(tǒng)中的一個(gè)初始根文件系統(tǒng)。initrd 與內(nèi)核綁定在一起,并作為內(nèi)核引導(dǎo)過(guò)程的一部分進(jìn)行加載。內(nèi)核然后會(huì)將這個(gè) initrd 文件作為其兩階段引導(dǎo)過(guò)程的一部分來(lái)加載模塊,這樣才能稍后使用真正的文件系統(tǒng),并掛載實(shí)際的根文件系統(tǒng)。
initrd 中包含了實(shí)現(xiàn)這個(gè)目標(biāo)所需要的目錄和可執(zhí)行程序的最小集合,例如將內(nèi)核模塊加載到內(nèi)核中所使用的 insmod 工具。
在桌面或服務(wù)器 Linux 系統(tǒng)中,initrd 是一個(gè)臨時(shí)的文件系統(tǒng)。其生存周期很短,只會(huì)用作到真實(shí)文件系統(tǒng)的一個(gè)橋梁。在沒(méi)有存儲(chǔ)設(shè)備的嵌入式系統(tǒng)中,initrd 是永久的根文件系統(tǒng)。本文將對(duì)這兩種情況進(jìn)行探索。
initrd剖析
initrd 映像中包含了支持 Linux 系統(tǒng)兩階段引導(dǎo)過(guò)程所需要的必要可執(zhí)行程序和系統(tǒng)文件。
根據(jù)我們運(yùn)行的 Linux 的版本不同,創(chuàng)建初始 RAM 磁盤(pán)的方法也可能會(huì)有所不同。在 Fedora Core 3 之前,initrd 是使用 loop 設(shè)備 來(lái)構(gòu)建的。loop 設(shè)備 是一個(gè)設(shè)備驅(qū)動(dòng)程序,利用它可以將文件作為一個(gè)塊設(shè)備掛載到系統(tǒng)中,然后就可以查看這個(gè)文件系統(tǒng)中的內(nèi)容了。在您的內(nèi)核中可能并沒(méi)有 loop 設(shè)備,不過(guò)這可以通過(guò)內(nèi)核配置工具(make menuconfig)選擇 Device Drivers > Block Devices > Loopback Device Support 來(lái)啟用。我們可以按照下面的方法來(lái)查看 loop 設(shè)備的內(nèi)容(initrd 文件的名字可能會(huì)稍有不同):
清單 1. 查看 initrd 的內(nèi)容(適用于 FC3 之前的版本)
# mkdir temp ; cd temp
# cp /boot/initrd.img.gz .
# gunzip initrd.img.gz
# mount -t ext -o loop initrd.img /mnt/initrd
# ls -la /mnt/initrd
現(xiàn)在我們就可以查看 /mnt/initrd 子目錄中的內(nèi)容了,這就代表了 initrd 文件的內(nèi)容。注意,即使您的 initrd 映像文件不是以 .gz 結(jié)尾,它也可能是一個(gè)壓縮文件,您可以給這個(gè)文件添加上 .gz 后綴,然后再使用 gunzip 對(duì)其進(jìn)行解壓。
從 Fedora Core 3 開(kāi)始,默認(rèn)的 initrd 映像變成了一個(gè)經(jīng)過(guò)壓縮的 cpio 歸檔文件。我們不用再使用 loop 設(shè)備來(lái)將 initrd 作為壓縮映像進(jìn)行掛載,而是可以將其作為 cpio 歸檔文件來(lái)使用。要查看 cpio 歸檔文件的內(nèi)容,可以使用下面的命令:
清單 2. 查看 initrd 的內(nèi)容(適用于 FC3 及其以后的版本)
# mkdir temp ; cd temp
# cp /boot/initrd-2.6.14.2.img initrd-2.6.14.2.img.gz
# gunzip initrd-2.6.14.2.img.gz
# cpio -i --make-directories < initrd-2.6.14.2.img
#
結(jié)果會(huì)生成一個(gè)很小的根文件系統(tǒng),如清單 3 所示。在 ./bin 目錄中有一組很少但卻非常必要的應(yīng)用程序,包括 nash(即 not a shell,是一個(gè)腳本解釋器)、insmod(用來(lái)加載內(nèi)核模塊)和 lvm(邏輯卷管理工具)。
清單 3. 默認(rèn)的 Linux initrd 目錄結(jié)構(gòu)
# ls -la
#
drwxr-xr-x? 10 root root??? 4096 May 7 02:48 .
drwxr-x---? 15 root root??? 4096 May 7 00:54 ..
drwxr-xr-x? 2? root root??? 4096 May 7 02:48 bin
drwxr-xr-x? 2? root root??? 4096 May 7 02:48 dev
drwxr-xr-x? 4? root root??? 4096 May 7 02:48 etc
-rwxr-xr-x? 1? root root???? 812 May 7 02:48 init
-rw-r--r--? 1? root root 1723392 May 7 02:45 initrd-2.6.14.2.img
drwxr-xr-x? 2? root root??? 4096 May 7 02:48 lib
drwxr-xr-x? 2? root root??? 4096 May 7 02:48 loopfs
drwxr-xr-x? 2? root root??? 4096 May 7 02:48 proc
lrwxrwxrwx? 1? root root?????? 3 May 7 02:48 sbin -> bin
drwxr-xr-x? 2? root root??? 4096 May 7 02:48 sys
drwxr-xr-x? 2? root root??? 4096 May 7 02:48 sysroot
#
清單 3 中比較有趣的是 init 文件就在根目錄中。與傳統(tǒng)的 Linux 引導(dǎo)過(guò)程類(lèi)似,這個(gè)文件也是在將 initrd 映像解壓到 RAM 磁盤(pán)中時(shí)被調(diào)用的。在本文稍后我們將來(lái)探索這個(gè)問(wèn)題。
創(chuàng)建 initrd 所使用的工具
cpio 命令
使用 cpio 命令,我們可以對(duì) cpio 文件進(jìn)行操作。cpio 是一種文件格式,它簡(jiǎn)單地使用文件頭將一組文件串接在一起。cpio 文件格式可以使用 ASCII 和二進(jìn)制文件。為了保證可移植性,我們可以使用 ASCII 格式。為了減小文件大小,我們可以使用二進(jìn)制的版本。
下面讓我們回到最開(kāi)始,來(lái)看一下 initrd 映像最初是如何構(gòu)建的。對(duì)于傳統(tǒng)的 Linux 系統(tǒng)來(lái)說(shuō),initrd 映像是在 Linux 構(gòu)建過(guò)程中創(chuàng)建的。有很多工具,例如 mkinitrd,都可以用來(lái)使用必要的庫(kù)和模塊自動(dòng)構(gòu)建 initrd,從而用作與真實(shí)的根文件系統(tǒng)之間的橋梁。mkinitrd 工具實(shí)際上就是一個(gè) shell 腳本,因此我們可以看到它究竟是如何來(lái)實(shí)現(xiàn)這個(gè)結(jié)果的。還有一個(gè) YAIRD(即 Yet Another Mkinitrd)工具,可以對(duì) initrd 構(gòu)建過(guò)程的各個(gè)方面進(jìn)行定制。
手工構(gòu)建定制的初始 RAM 磁盤(pán)
由于在很多基于 Linux 的嵌入式系統(tǒng)上沒(méi)有硬盤(pán),因此 initrd 也會(huì)作為這種系統(tǒng)上的永久根文件系統(tǒng)使用。清單 4 顯示了如何創(chuàng)建一個(gè) initrd 映像文件。我使用了一個(gè)標(biāo)準(zhǔn)的 Linux 桌面,這樣您即使沒(méi)有嵌入式平臺(tái),也可以按照下面的步驟來(lái)執(zhí)行了。除了交叉編譯,其他概念(也適用于 initrd 的構(gòu)建)對(duì)于嵌入式平臺(tái)都是相同的。
清單 4. 創(chuàng)建定制 initrd 的工具(mkird)
#!/bin/bash
# Housekeeping...
rm -f /tmp/ramdisk.img
rm -f /tmp/ramdisk.img.gz
# Ramdisk Constants
RDSIZE=4000
BLKSIZE=1024
# Create an empty ramdisk image
dd if=/dev/zero of=/tmp/ramdisk.img bs=$BLKSIZE count=$RDSIZE
# Make it an ext2 mountable file system
/sbin/mke2fs -F -m 0 -b $BLKSIZE /tmp/ramdisk.img $RDSIZE
# Mount it so that we can populate
mount /tmp/ramdisk.img /mnt/initrd -t ext2 -o loop=/dev/loop0
# Populate the filesystem (subdirectories)
mkdir /mnt/initrd/bin
mkdir /mnt/initrd/sys
mkdir /mnt/initrd/dev
mkdir /mnt/initrd/proc
# Grab busybox and create the symbolic links
pushd /mnt/initrd/bin
cp /usr/local/src/busybox-1.1.1/busybox .
ln -s busybox ash
ln -s busybox mount
ln -s busybox echo
ln -s busybox ls
ln -s busybox cat
ln -s busybox ps
ln -s busybox dmesg
ln -s busybox sysctl
popd
# Grab the necessary dev files
cp -a /dev/console /mnt/initrd/dev
cp -a /dev/ramdisk /mnt/initrd/dev
cp -a /dev/ram0 /mnt/initrd/dev
cp -a /dev/null /mnt/initrd/dev
cp -a /dev/tty1 /mnt/initrd/dev
cp -a /dev/tty2 /mnt/initrd/dev
# Equate sbin with bin
pushd /mnt/initrd
ln -s bin sbin
popd
# Create the init file
cat >> /mnt/initrd/linuxrc << EOF
#!/bin/ash
echo
echo "Simple initrd is active"
echo
mount -t proc /proc /proc
mount -t sysfs none /sys
/bin/ash --login
EOF
chmod +x /mnt/initrd/linuxrc
# Finish up...
umount /mnt/initrd
gzip -9 /tmp/ramdisk.img
cp /tmp/ramdisk.img.gz /boot/ramdisk.img.gz
initrd Linux 發(fā)行版
Minimax 是一個(gè)開(kāi)放源碼項(xiàng)目,其設(shè)計(jì)目標(biāo)是成為一個(gè)全部封裝在 initrd 中的 Linux 發(fā)行版。它的大小是 32MB,為了盡量小,它使用了 BusyBox 和 uClibc。除了非常小之外,它還使用了 2.6 版本的 Linux 內(nèi)核,并提供了很多有用的工具。
ext2 文件系統(tǒng)的替代品
盡管 ext2 是一種通用的 Linux 文件系統(tǒng)格式,但是還有一些替代品可以減小 initrd 映像文件以及所掛載上來(lái)的文件系統(tǒng)的大小。這種文件系統(tǒng)的例子有 romfs(ROM 文件系統(tǒng))、cramfs(壓縮 ROM 文件系統(tǒng))和 squashfs(高度壓縮只讀文件系統(tǒng))。如果我們需要暫時(shí)將數(shù)據(jù)寫(xiě)入文件系統(tǒng)中,ext2 可以很好地實(shí)現(xiàn)這種功能。最后,e2compr 是 ext2 文件系統(tǒng)驅(qū)動(dòng)程序的一個(gè)擴(kuò)展,可以支持在線(xiàn)壓縮。
為了創(chuàng)建 initrd,我們最開(kāi)始創(chuàng)建了一個(gè)空文件,這使用了 /dev/zero(一個(gè)由零組成的碼流)作為輸入,并將其寫(xiě)入到 ramdisk.img 文件中。所生成的文件大小是 4MB(4000 個(gè) 1K 大小的塊)。然后使用 mke2fs 命令在這個(gè)空文件上創(chuàng)建了一個(gè) ext2(即 second extended)文件系統(tǒng)?,F(xiàn)在這個(gè)文件變成了一個(gè) ext2 格式的文件系統(tǒng),我們使用 loop 設(shè)備將這個(gè)文件掛載到 /mnt/initrd 上了。在這個(gè)掛載點(diǎn)上,我們現(xiàn)在就有了一個(gè)目錄,它以 ext2 文件系統(tǒng)的形式呈現(xiàn)出來(lái),我們可以對(duì)自己的 initrd 文件進(jìn)行拼裝了。接下來(lái)的腳本提供了這種功能。
下一個(gè)步驟是創(chuàng)建構(gòu)成根文件系統(tǒng)所需要的子目錄:/bin、/sys、/dev 和 /proc。這里只列出了所需要的目錄(例如沒(méi)有庫(kù)),但是其中包含了很多功能。
為了可以使用根文件系統(tǒng),我們使用了 BusyBox。這個(gè)工具是一個(gè)單一映像,其中包含了很多在 Linux 系統(tǒng)上通??梢哉业降墓ぞ撸ɡ?ash、awk、sed、insmod 等)。BusyBox 的優(yōu)點(diǎn)是它將很多工具打包成一個(gè)文件,同時(shí)還可以共享它們的通用元素,這樣可以極大地減少映像文件的大小。這對(duì)于嵌入式系統(tǒng)來(lái)說(shuō)非常理想。將 BusyBox 映像從自己的源目錄中拷貝到自己根目錄下的 /bin 目錄中。然后創(chuàng)建了很多符號(hào)鏈接,它們都指向 BusyBox 工具。BusyBox 會(huì)判斷所調(diào)用的是哪個(gè)工具,并執(zhí)行這個(gè)工具的功能。我們?cè)谶@個(gè)目錄中創(chuàng)建了幾個(gè)鏈接來(lái)支持 init 腳本(每個(gè)命令都是一個(gè)指向 BusyBox 的鏈接。)
下一個(gè)步驟是創(chuàng)建幾個(gè)特殊的設(shè)備文件。我從自己當(dāng)前的 /dev 子目錄中直接拷貝了這些文件,這使用了 -a 選項(xiàng)(歸檔)來(lái)保留它們的屬性。
倒數(shù)第二個(gè)步驟是生成 linuxrc 文件。在內(nèi)核掛載 RAM 磁盤(pán)之后,它會(huì)查找 init 文件來(lái)執(zhí)行。如果沒(méi)有找到 init 文件,內(nèi)核就會(huì)調(diào)用 linuxrc 文件作為自己的啟動(dòng)腳本。我們?cè)谶@個(gè)文件中實(shí)現(xiàn)對(duì)環(huán)境的基本設(shè)置,例如掛載 /proc 文件系統(tǒng)。除了 /proc 之外,我還掛載了 /sys 文件系統(tǒng),并向終端打印一條消息。最后,我們調(diào)用了 ash(一個(gè) Bourne Shell 的克?。@樣就可以與根文件系統(tǒng)進(jìn)行交互了。linuxrc 文件然后使用 chmod 命令修改成可執(zhí)行的。
最后,我們的根文件系統(tǒng)就完成了。我們將其卸載掉,然后使用 gzip 對(duì)其進(jìn)行壓縮。所生成的文件(ramdisk.img.gz)被拷貝到 /boot 子目錄中,這樣就可以通過(guò) GNU GRUB 對(duì)其進(jìn)行加載了。
要構(gòu)建初始 RAM 磁盤(pán),我們可以簡(jiǎn)單地調(diào)用 mkird,這樣就會(huì)自動(dòng)創(chuàng)建這個(gè)映像文件,并將其拷貝到 /boot 目錄中。
測(cè)試定制的初始 RAM 磁盤(pán)
Linux 內(nèi)核中對(duì) initrd 的支持
對(duì)于 Linux 內(nèi)核來(lái)說(shuō),要支持初始 RAM 磁盤(pán),內(nèi)核必須要使用 CONFIG_BLK_DEV_RAM 和 CONFIG_BLK_DEV_INITRD 選項(xiàng)進(jìn)行編譯。
新的 initrd 映像現(xiàn)在已經(jīng)在 /boot 目錄中了,因此下一個(gè)步驟是使用默認(rèn)的內(nèi)核來(lái)對(duì)其進(jìn)行測(cè)試?,F(xiàn)在我們可以重新啟動(dòng) Linux 系統(tǒng)了。在出現(xiàn) GRUB 界面時(shí),按 C 鍵啟動(dòng) GRUB 中的命令行工具。我們現(xiàn)在可以與 GRUB 進(jìn)行交互,從而定義要加載哪個(gè)內(nèi)核和 initrd 映像文件。kernel 命令讓我們可以指定內(nèi)核文件,initrd 命令可以用來(lái)指定 initrd 映像文件。在定義好這些參數(shù)之后,就可以使用 boot 命令來(lái)引導(dǎo)內(nèi)核了,如清單 5 所示。
清單 5. 使用 GRUB 手工引導(dǎo)內(nèi)核和 initrd
GNU GRUB? version 0.95? (638K lower / 97216K upper memory)
[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename. ESC at any time exits.]
grub> kernel /bzImage-2.6.1
[Linux-bzImage, setup=0x1400, size=0x29672e]
grub> initrd /ramdisk.img.gz
[Linux-initrd @ 0x5f2a000, 0xb5108 bytes]
grub> boot
Uncompressing Linux... OK, booting the kernel.
在內(nèi)核啟動(dòng)之后,它會(huì)檢查是否有 initrd 映像文件可用(稍后會(huì)更詳細(xì)介紹),然后將其加載,并將其掛載成根文件系統(tǒng)。在清單 6 中我們可以看到這個(gè) Linux 啟動(dòng)過(guò)程最后的樣子。在啟動(dòng)之后,ash shell 就可以用來(lái)輸入命令了。在這個(gè)例子中,我們將瀏覽一下根文件系統(tǒng)的內(nèi)容,并查看一下虛擬 proc 文件系統(tǒng)中的內(nèi)容。我們還展示了如何通過(guò) touch 命令在文件系統(tǒng)中創(chuàng)建文件。注意所創(chuàng)建的第一個(gè)進(jìn)程是 linuxrc(通常都是 init)。
清單 6. 使用簡(jiǎn)單的 initrd 引導(dǎo) Linux 內(nèi)核
...
md: Autodetecting RAID arrays
md: autorun
md: ... autorun DONE.
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 file system).
Freeing unused kernel memory: 208k freed
/ $ ls
bin???????? etc?????? linuxrc?????? proc??????? sys
dev???????? lib?????? lost+found??? sbin
/ $ cat /proc/1/cmdline
/bin/ash/linuxrc
/ $ cd bin
/bin $ ls
ash????? cat????? echo???? mount??? sysctl
busybox? dmesg??? ls???? ??ps
/bin $ touch zfile
/bin $ ls
ash????? cat????? echo???? mount??? sysctl
busybox? dmesg??? ls?????? ps?????? zfile
使用初始 RAM 磁盤(pán)來(lái)引導(dǎo)系統(tǒng)
現(xiàn)在我們已經(jīng)了解了如何構(gòu)建并使用定制的初始 RAM 磁盤(pán),本節(jié)將探索內(nèi)核是如何識(shí)別 initrd 并將其作為根文件系統(tǒng)進(jìn)行掛載的。我們將介紹啟動(dòng)鏈中的幾個(gè)主要函數(shù),并解釋一下到底在進(jìn)行什么操作。
引導(dǎo)加載程序,例如 GRUB,定義了要加載的內(nèi)核,并將這個(gè)內(nèi)核映像以及相關(guān)的 initrd 拷貝到內(nèi)存中。我們可以在 Linux 內(nèi)核源代碼目錄中的 ./init 子目錄中找到很多這種功能。
在內(nèi)核和 initrd 映像被解壓并拷貝到內(nèi)存中之后,內(nèi)核就會(huì)被調(diào)用了。它會(huì)執(zhí)行不同的初始化操作,最終您會(huì)發(fā)現(xiàn)自己到了 init/main.c:init()(subdir/file:function)函數(shù)中。這個(gè)函數(shù)執(zhí)行了大量的子系統(tǒng)初始化操作。此處會(huì)執(zhí)行一個(gè)對(duì) init/do_mounts.c:prepare_namespace() 的調(diào)用,這個(gè)函數(shù)用來(lái)準(zhǔn)備名稱(chēng)空間(掛載 dev 文件系統(tǒng)、RAID 或 md、設(shè)備以及最后的 initrd)。加載 initrd 是通過(guò)調(diào)用 init/do_mounts_initrd.c:initrd_load() 實(shí)現(xiàn)的。
initrd_load() 函數(shù)調(diào)用了 init/do_mounts_rd.c:rd_load_image(),它通過(guò)調(diào)用 init/do_mounts_rd.c:identify_ramdisk_image() 來(lái)確定要加載哪個(gè) RAM 磁盤(pán)。這個(gè)函數(shù)會(huì)檢查映像文件的 magic 號(hào)來(lái)確定它是 minux、etc2、romfs、cramfs 或 gzip 格式。在返回到 initrd_load_image 之前,它還會(huì)調(diào)用 init/do_mounts_rd:crd_load()。這個(gè)函數(shù)負(fù)責(zé)為 RAM 磁盤(pán)分配空間,并計(jì)算循環(huán)冗余校驗(yàn)碼(CRC),然后對(duì) RAM 磁盤(pán)映像進(jìn)行解壓,并將其加載到內(nèi)存中?,F(xiàn)在,我們?cè)谝粋€(gè)適合掛載的塊設(shè)備中就有了這個(gè) initrd 映像。
現(xiàn)在使用一個(gè) init/do_mounts.c:mount_root() 調(diào)用將這個(gè)塊設(shè)備掛載到根文件系統(tǒng)上。它會(huì)創(chuàng)建根設(shè)備,并調(diào)用 init/do_mounts.c:mount_block_root()。在這里調(diào)用 init/do_mounts.c:do_mount_root(),后者又會(huì)調(diào)用 fs/namespace.c:sys_mount() 來(lái)真正掛載根文件系統(tǒng),然后 chdir 到這個(gè)文件系統(tǒng)中。這就是我們?cè)谇鍐?6 中所看到的熟悉消息 VFS: Mounted root (ext2 file system). 的地方。
最后,返回到 init 函數(shù)中,并調(diào)用 init/main.c:run_init_process。這會(huì)導(dǎo)致調(diào)用 execve 來(lái)啟動(dòng) init 進(jìn)程(在本例中是 /linuxrc)。linuxrc 可以是一個(gè)可執(zhí)行程序,也可以是一個(gè)腳本(條件是它有腳本解釋器可用)。
這些函數(shù)的調(diào)用層次結(jié)構(gòu)如清單 7 所示。盡管此處并沒(méi)有列出拷貝和掛載初始 RAM 磁盤(pán)所涉及的所有函數(shù),但是這足以為我們提供一個(gè)整體流程的粗略框架。
清單 7. initrd 加載和掛載過(guò)程中所使用的主要函數(shù)的層次結(jié)構(gòu)
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
無(wú)盤(pán)引導(dǎo)
與嵌入式引導(dǎo)的情況類(lèi)似,本地磁盤(pán)(軟盤(pán)或 CD-ROM)對(duì)于引導(dǎo)內(nèi)核和 ramdisk 根文件系統(tǒng)來(lái)說(shuō)都不是必需的。DHCP(Dynamic Host Configuration Protocol)可以用來(lái)確定網(wǎng)絡(luò)參數(shù),例如 IP 地址和子網(wǎng)掩碼。TFTP(Trivial File Transfer Protocol)可以用來(lái)將內(nèi)核映像和初始 ramdisk 映像傳輸?shù)奖镜卦O(shè)備上。傳輸完成之后,就可以引導(dǎo) Linux 內(nèi)核并掛載 initrd 了,這與本地映像引導(dǎo)的過(guò)程類(lèi)似。
壓縮 initrd
在構(gòu)建嵌入式系統(tǒng)時(shí),我們可能希望將 initrd 映像文件做得盡可能小,這其中有一些技巧需要考慮。首先是使用 BusyBox(本文中已經(jīng)展示過(guò)了)。BusyBox 可以將數(shù) MB 的工具壓縮成幾百 KB。
在這個(gè)例子中,BusyBox 映像是靜態(tài)鏈接的,因此它不需要其他庫(kù)。然而,如果我們需要標(biāo)準(zhǔn)的 C 庫(kù)(我們自己定制的二進(jìn)制可能需要這個(gè)庫(kù)),除了巨大的 glibc 之外,我們還有其他選擇。第一個(gè)較小的庫(kù)是 uClibc,這是為對(duì)空間要求非常嚴(yán)格的系統(tǒng)準(zhǔn)備的一個(gè)標(biāo)準(zhǔn) C 庫(kù)。另外一個(gè)適合空間緊張的環(huán)境的庫(kù)是 dietlib。要記住我們需要使用這些庫(kù)來(lái)重新編譯想在嵌入式系統(tǒng)中重新編譯的二進(jìn)制文件,因此這需要額外再做一些工作(但是這是非常值得的)。
結(jié)束語(yǔ)
初始 RAM 磁盤(pán)最初是設(shè)計(jì)用來(lái)通過(guò)一個(gè)臨時(shí)根文件系統(tǒng)來(lái)作為內(nèi)核到最終的根文件系統(tǒng)之間的橋梁。initrd 對(duì)于在嵌入式系統(tǒng)中加載到 RAM 磁盤(pán)里的非持久性根文件系統(tǒng)來(lái)說(shuō)也非常有用。
?
電子發(fā)燒友App


























評(píng)論