Linux? 初始 RAM 磁盤(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 磁盤卸載,并釋放內(nèi)存。在很多嵌入式 Linux 系統(tǒng)中,initrd 就是最終的根文件系統(tǒng)。本文將探索 Linux 2.6 的初始 RAM 磁盤,包括如何創(chuàng)建以及如何在 Linux 內(nèi)核中使用。
什么是初始 RAM 磁盤?
初始 RAM 磁盤(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 磁盤的方法也可能會(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 開始,默認(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ò)程類似,這個(gè)文件也是在將 initrd 映像解壓到 RAM 磁盤中時(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)制的版本。
下面讓我們回到最開始,來(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 磁盤
由于在很多基于 Linux 的嵌入式系統(tǒng)上沒(méi)有硬盤,因此 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è)開放源碼項(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ù)寫入文件系統(tǒng)中,ext2 可以很好地實(shí)現(xiàn)這種功能。最后,e2compr 是 ext2 文件系統(tǒng)驅(qū)動(dòng)程序的一個(gè)擴(kuò)展,可以支持在線壓縮。
為了創(chuàng)建 initrd,我們最開始創(chuàng)建了一個(gè)空文件,這使用了 /dev/zero(一個(gè)由零組成的碼流)作為輸入,并將其寫入到 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 磁盤之后,它會(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 磁盤,我們可以簡(jiǎn)單地調(diào)用 mkird,這樣就會(huì)自動(dòng)創(chuàng)建這個(gè)映像文件,并將其拷貝到 /boot 目錄中。
測(cè)試定制的初始 RAM 磁盤
Linux 內(nèi)核中對(duì) initrd 的支持
對(duì)于 Linux 內(nèi)核來(lái)說(shuō),要支持初始 RAM 磁盤,內(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 磁盤來(lái)引導(dǎo)系統(tǒng)
現(xiàn)在我們已經(jīng)了解了如何構(gòu)建并使用定制的初始 RAM 磁盤,本節(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)備名稱空間(掛載 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 磁盤。這個(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 磁盤分配空間,并計(jì)算循環(huán)冗余校驗(yàn)碼(CRC),然后對(duì) RAM 磁盤映像進(jìn)行解壓,并將其加載到內(nèi)存中。現(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 磁盤所涉及的所有函數(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ú)盤引導(dǎo)
與嵌入式引導(dǎo)的情況類似,本地磁盤(軟盤或 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ò)程類似。
壓縮 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 磁盤最初是設(shè)計(jì)用來(lái)通過(guò)一個(gè)臨時(shí)根文件系統(tǒng)來(lái)作為內(nèi)核到最終的根文件系統(tǒng)之間的橋梁。initrd 對(duì)于在嵌入式系統(tǒng)中加載到 RAM 磁盤里的非持久性根文件系統(tǒng)來(lái)說(shuō)也非常有用。
?
評(píng)論
查看更多