- 論壇徽章:
- 0
|
轉(zhuǎn)自:http://www.91linux.com/html/article/qianrushiyingyong/20081110/13741.html
深入理解 Linux 2.6 的 initramfs 機(jī)制 (上)
日前結(jié)束一個(gè)消費(fèi)性電子產(chǎn)品的開(kāi)發(fā)工作,稍有心得,試著整理採(cǎi)取 Linux kernel 2.6 initramfs
機(jī)制以加速系統(tǒng)開(kāi)發(fā)的經(jīng)驗(yàn),同時(shí)也談?wù)搶?duì) fast-booting 設(shè)計(jì)的重要性,順便解決某些像是「kinit/klibc
為何被提出?」等疑難雜癥。
進(jìn)
入主題前,先看看所謂的 booting。相傳在十八世紀(jì),德國(guó) Baron Münchhausen
男爵常誇大吹噓自己的英勇事蹟,其中一項(xiàng)是「拉著自己的頭髮?zhuān)瑢⒆约簭氖芟莸恼訚芍刑崞稹,此事後?lái)收錄於德國(guó)《吹牛大王歷險(xiǎn)記》,則改寫(xiě)為「用拔靴帶把
自己從海中拉起來(lái)」,這裡的「拔靴帶」(bootstrap)
指的是長(zhǎng)統(tǒng)靴靴筒頂端後方的小環(huán)帶,是用以輔助穿長(zhǎng)統(tǒng)靴。這種有違物理原理的誇大動(dòng)作,卻讓不同領(lǐng)域的人們獲得靈感,Robert A.
Heinlein 發(fā)表於 1941 年的短文〈By His Bootstraps〉收錄典故並給予多種延伸想法;滑鼠發(fā)明人
Doug Engelbart
博士甚至在 1989 年以此命名其研究機(jī)構(gòu)「Bootstrap 學(xué)院」,並擔(dān)任該院主任。在商業(yè)上,bootstrapping
則被引申為一種創(chuàng)業(yè)模式,也就是初期投入少量的啟動(dòng)資本,然後在創(chuàng)業(yè)過(guò)程中主要依靠從客戶(hù)得來(lái)的銷(xiāo)售收入,形成一個(gè)良好的正現(xiàn)金流。在電腦資訊領(lǐng)域,因?yàn)?br />
開(kāi)機(jī)過(guò)程是環(huán)環(huán)相扣,先透過(guò)簡(jiǎn)單的程式讀入記憶體,執(zhí)行後又載入更多磁區(qū)、程式碼來(lái)執(zhí)行,直到作業(yè)系統(tǒng)完全載入為止,所以開(kāi)機(jī)過(guò)程也被稱(chēng)為
bootstrapping,簡(jiǎn)稱(chēng) "boot"。
自 1991 年 Linux 問(wèn)世以來(lái),資訊技術(shù)的應(yīng)用有了極大的轉(zhuǎn)變,筆者之前的文章 [
探索 Linux bootloader 的佳作
] 與 [
kboot 初探與模擬驗(yàn)證
]
約略提及光是開(kāi)機(jī)本身的設(shè)計(jì)來(lái)說(shuō),就有多種衝擊與需求,隨著 Linux 走出個(gè)人電腦領(lǐng)域,在嵌入式系統(tǒng)應(yīng)用上,更是五花八門(mén)。本文所探討的
initramfs,衍生自 Linux kernel 的 initrd,理解其設(shè)計(jì)需求是先行的準(zhǔn)備。initrd 字面上的意思就是 "boot
loader initialized RAM disk",換言之,這是一塊特殊的 RAM disk,在載入 Linux kernel 前,由
boot loader 予以初始化,具體動(dòng)作就是從特定的儲(chǔ)存裝置中載入 initrd 到 RAM 中 (由啟動(dòng)參數(shù) "initrd=" 指定
image 的實(shí)體或邏輯位置),隨後 linux kernel 被載入並執(zhí)行時(shí),會(huì)優(yōu)先處理置放 initrd
的記憶體空間,而這個(gè)空間基本上也有檔案系統(tǒng),通常會(huì)包含 init 等程式,故可用以?huà)烊肽承┨貏e的驅(qū)動(dòng)程式,比方說(shuō)
SCSI,完成階段性目標(biāo)後,kernel 會(huì)將真正的 root file system 掛載,並執(zhí)行 /sbin/init 程式。
話(huà)
說(shuō)回來(lái),我們?yōu)楹涡枰说扔剞挼拈_(kāi)機(jī)途徑呢?原因是,root file system (由啟動(dòng)參數(shù) "root=" 所指定,以下簡(jiǎn)稱(chēng)
rootfs) 所在的儲(chǔ)存裝置很可能極難尋找,比方說(shuō) SCSI 裝置就需要複雜且耗時(shí)的程序,若用 RAID
系統(tǒng)更是需要看配置情況而定,同樣的問(wèn)題也發(fā)生在 USB storage 上,因?yàn)?kernel 得花上更長(zhǎng)的等待與配置時(shí)間,或說(shuō)遠(yuǎn)端掛載
rootfs,不僅得處理網(wǎng)路裝置的問(wèn)題,甚至還得考慮相關(guān)的伺服器認(rèn)證、通訊往返時(shí)間等議題。更重要的是,我們可在 initrd
放置某些特別的程式,一來(lái)作為掛載 rootfs
作準(zhǔn)備,比方說(shuō)硬體初始化、解密、解壓縮等等,二來(lái)提示使用者或系統(tǒng)管理員目前的狀態(tài),這對(duì)於消費(fèi)性電子產(chǎn)品來(lái)說(shuō),有很大的意義。整體來(lái)說(shuō),如果能增加開(kāi)
機(jī)的彈性 (比方說(shuō)配合簡(jiǎn)單的 shell script 即可達(dá)成 USB/SCSI 初始化動(dòng)作,若透過(guò) kernel code
實(shí)做,恐怕上百千行是免不掉的),又能適度降低 kernel image 本身的設(shè)計(jì)複雜度與空間使用量,採(cǎi)取 initrd
是很不錯(cuò)的方式,所以幾乎各大 Linux distribution 都有提供
initrd,以解決在不同硬體、不同裝置上開(kāi)機(jī)的技術(shù)議題,也能確保一片 CD-ROM/DVD 可裝入多種個(gè)人電腦系統(tǒng),也可支援 [
bootsplash
] 一類(lèi)顯示開(kāi)機(jī)動(dòng)畫(huà)的程式。
具
體來(lái)說(shuō),initrd 提供了「兩階段開(kāi)機(jī)」程序。首先,一切都還是在 kernel mode,由 kernel
完成與硬體相關(guān)的初始化工作,接著,在適當(dāng)?shù)臅r(shí)機(jī)點(diǎn),當(dāng) kernel 讀取並掛載 initrd 所在記憶體空間的檔案系統(tǒng)後,kernel 首次從
kernel space 切入 user space,以執(zhí)行存放於 RAM disk 中的 init 程式,當(dāng)然,這需要完整的執(zhí)行環(huán)境
(比方說(shuō) C runtime 或必要的 program loader 等),另外,也得確定 rootfs 可被 kernel
所找到並正確掛載。待第一階段的 initrd 步入尾聲後,再回到 kernel mode,initrd 所在的記憶體空間也會(huì)適度被釋放
(依據(jù)組態(tài)而定),這才進(jìn)入第二階段,也就是執(zhí)行真正的 rootfs 中的 init 程式。在 Linux kernel 2.4
中,initrd 大致的處理流程如下:(方括號(hào)表示主要的執(zhí)行單元)
- [boot loader] Boot loader 依據(jù)預(yù)先設(shè)定的條件,將 kernel 與 initrd 這兩個(gè) image 載入到 RAM
- [boot loader -> kernel] 完成必要的動(dòng)作後,準(zhǔn)備將執(zhí)行權(quán)交給 Linux kernel
- [kernel] 進(jìn)行一系列初始化動(dòng)作,initrd 所在的記憶體被 kernel 對(duì)應(yīng)為 /dev/initrd 裝置設(shè)備,透過(guò) kernel 內(nèi)部的 decompressor (gzip 解壓縮) 解開(kāi)該內(nèi)容並複製到 /dev/ram0 裝置設(shè)備上
- [kernel] Linux 以 R/W (可讀寫(xiě)) 模式將 /dev/ram0 掛載為暫時(shí)性的 rootfs
- [kernel-space -> user-space] kernel 準(zhǔn)備執(zhí)行 /dev/ram0 上的 /linuxrc 程式,並切換執(zhí)行流程
- [user space] /linuxrc 與相關(guān)的程式處理特定的操作,比方說(shuō)準(zhǔn)備掛載 rootfs 等
- [user-space -> kernel-space] /linuxrc 執(zhí)行即將完畢,執(zhí)行權(quán)轉(zhuǎn)交給 kernel
- [kernel] Linux 掛載真正的 rootfs 並執(zhí)行 /sbin/init 程式
- [user space] 依據(jù) Linux distribution 規(guī)範(fàn)的流程,執(zhí)行各式系統(tǒng)與應(yīng)用程式
值得一提的是,以上「兩階段開(kāi)機(jī)」是 initrd 提出的彈性開(kāi)機(jī)流程,在真實(shí)的應(yīng)用中,也可能從未需要掛載真正的
rootfs,換言之,只是把系統(tǒng)當(dāng)作都在 RAM disk 上運(yùn)作,或者永遠(yuǎn)都在 initrd 所引導(dǎo)執(zhí)行的 /linuxrc 程序中執(zhí)行
(注意:kernel 永遠(yuǎn)保留 PID=1 作為 init process 識(shí)別,而 /linuxrc 執(zhí)行的 PID 必非為
1),在許多裝置如智慧型手機(jī),都是行之有年的,不過(guò)這不影響我們後續(xù)的探討。
Linux
Kernel 的發(fā)展文化就是願(yuàn)意捨棄既有實(shí)做,大膽採(cǎi)用新的途徑 (在符合國(guó)際規(guī)格的前提下),Linux 2.6 的 initramfs
之所以提出,就是要修正 initrd 的種種技術(shù)問(wèn)題。問(wèn)題在哪呢?首先,回顧剛剛探討的流程,initrd RAM disk 對(duì) kernel
來(lái)說(shuō),本身是個(gè)真實(shí)的 block device,為了建構(gòu)存放其中的檔案 (最起碼要有 /linuxrc),通常我們需要 ext2
一類(lèi)的檔案系統(tǒng) (建議)。所以,就建構(gòu)如此的 initrd image 來(lái)看,通常會(huì)透過(guò) mkfs.ext2 與 losetup
(功能:"set up and control loop devices") 等工具建立 loopback device
並編修,所以自然需面對(duì)以下問(wèn)題:
- initrd 必須綁定某個(gè)檔案系統(tǒng)實(shí)做,如 ext2,可是多數(shù)的情況下,我們根本不需要在此階段擁有完整的實(shí)做
- /dev/initrd block device 建構(gòu)時(shí)即有空間限制,維護(hù)繁瑣
- 運(yùn)作於 initrd 階段,檔案操作實(shí)際上是不斷將 /dev/initrd (對(duì)應(yīng)於某段記憶體) 對(duì)應(yīng)到可存取檔案系統(tǒng)的記憶位址,做了不必要的資源消耗
Kernel 文件 ( Documentation/filesystems/ramfs-rootfs-initramfs.txt ) 更指出:
Another reason ramdisks are
semi-obsolete is that the introduction of loopback devices offered a
more flexible and convenient way to create synthetic block devices, now
from files instead of from chunks of memory.
基於上述資源使用與效能考量,原本 ramdisk 途徑就被標(biāo)示為「老舊」,而 initramfs 的提出,則是基於更簡(jiǎn)單有效率的 ramfs 與新的處理方式。
回
到 initrd ramdisk,事實(shí)上,原本的設(shè)計(jì)甚至更加浪費(fèi)記憶體,因?yàn)?Linux 在設(shè)計(jì)上就會(huì)盡可能將讀入/寫(xiě)入自 block
device 的檔案或目錄予以 cache,所以,Linux 會(huì)自 ramdisk 中複製資料到 page cache 與 dentry
cache,如此往返,徒增資源使用的浪費(fèi),這一切問(wèn)題的根源就是將 initrd 以 block device 來(lái)操作的本質(zhì)使然。Linus
Torvalds 為此提出一個(gè)想法: 能否將這些 cache 被掛載為檔案系統(tǒng)呢?就在 cache 中保持這些檔案,但不清除這些,直到實(shí)際上被刪去或者系統(tǒng)重啟。
基於這些想法,Linus Torvalds 實(shí)做了 ramfs,隨後在其他核心開(kāi)發(fā)者的改進(jìn)下,成為 tmpfs,支援寫(xiě)入 swap
空間與限制記憶體使用量等特徵。而,initramfs 就是建構(gòu)於 tmpfs
的基礎(chǔ)上。採(cǎi)取此途徑的效益就是,檔案系統(tǒng)可自行調(diào)整空間使用量,以符合所需資料儲(chǔ)存的空間,同時(shí),也不再會(huì)有重複的 block device 與
cache 資料,因?yàn)楦静恍枰匾氖,這樣的檔案系統(tǒng)實(shí)做,其實(shí)就只是 cache
機(jī)制的延伸,沒(méi)有太多新的程式碼,所以系統(tǒng)可保持簡(jiǎn)單明暸。以下是對(duì) initrd 與 initramfs 的概念性比較:
initrd
initramfs
Image
壓縮過(guò)的檔案系統(tǒng) (如 ext2 + gzip)
封裝過(guò)的檔案 (cpio + gzip)
實(shí)做途徑
block device (RAM disk)
tmpfs
首先執(zhí)行的程式
/linuxrc
/init
掛載
rootfs 方式
將欲載入的 rootfs 掛載於某個(gè)目錄,再 pivot_root 切換 rootfs
使用 switch_root
前
面的段落已說(shuō)明這兩者對(duì)於記憶體存取與檔案操作的落差,同時(shí)也提及實(shí)做途徑,接下來(lái)的重點(diǎn)是這兩者如何看待真正的
rootfs。如同前述所及,Linux kernel 2.4 中,initrd 可被視為起始參數(shù) "root="
的先前處理機(jī)制,透過(guò)一系列的程序,協(xié)助 kernel 找到最終的 rootfs,並一舉掛載進(jìn)系統(tǒng),不過(guò),過(guò)去的設(shè)計(jì)其實(shí)做了一個(gè)假設(shè):「真正的
rootfs 所在的裝置是 block device,同時(shí) initrd 絕非是真正的 rootfs」,這也是為何要讓 kernel
在第一次準(zhǔn)備切入 user-space 時(shí),是執(zhí)行 /linuxrc,而非 /init 或 /sbin/init,因?yàn)獒嵴叩?PID 恆為 1
且不可被 kill (終止),但前者因?yàn)橹皇沁^(guò)度的存在,隨時(shí)仍可被 kill。
而在 Linux 2.6 引入
initramfs 的設(shè)計(jì)後,上述彆扭的假設(shè)與處理方式就不復(fù)存在,不再區(qū)隔「真正」的 rootfs 是如何「存在」,也就是一開(kāi)機(jī),kernel
就執(zhí)行位於 initramfs 中的 /init,作為 PID=1 的 init process,僅以 switch_root 作
rootfs 的重新定位罷了 (選擇性)。正因?yàn)檫@樣的特性,核心開(kāi)發(fā)者也將 initramfs 的行為稱(chēng)為 [
Early User Space
],Jeff Garzik 於 2002 年十一月發(fā)表於 lkml 的文章 [
initramfs merge, part 1 of N
] 提到他的願(yuàn)景:
The Future.
Early
userspace is going to be merged in a series of evolutionary changes,
following what I call "The Al Viro model." NO KERNEL BEHAVIOR SHOULD
CHANGE. [that's for the lkml listeners, not you ] "make" will
continue to simply Do The Right Thing(tm) on all platforms, while the
kernel image continues to get progressively smaller.
核心開(kāi)發(fā)者很喜歡彼此取笑,這裡提到的 [
Al Viro
]
是位知名的 kernel hacker,常常為了捍衛(wèi)核心設(shè)計(jì)的一致性與許多開(kāi)發(fā)者對(duì)立。這意思就是說(shuō),藉由 Early userspace
整合到核心設(shè)計(jì)後,原本很不容易處理的開(kāi)機(jī)模式,比方說(shuō) LVM (Linux Volume
Manager)、網(wǎng)路開(kāi)機(jī)、特別儲(chǔ)存裝置的開(kāi)機(jī)等,都可交由 user-space 的應(yīng)用程式專(zhuān)門(mén)處理,相對(duì)來(lái)說(shuō),kernel
就不必過(guò)度涉入,長(zhǎng)遠(yuǎn)來(lái)說(shuō),對(duì)於發(fā)展的分工、降低系統(tǒng)複雜度,以及提高可性賴(lài)度,均有很大的助益。
基於 initramfs /
Early userspace 的想法,核心開(kāi)發(fā)者又思考為何不將過(guò)去難以有效維護(hù)但又非得存在不可的程式碼,比方說(shuō) do_mount
這一類(lèi)用以實(shí)做掛載特定裝置或邏輯儲(chǔ)存設(shè)備的功能,全面轉(zhuǎn)交給 user-space 的程式去執(zhí)行呢?這樣 kernel
可專(zhuān)心提昇功能或者效能的改進(jìn)。為此,以 H. Peter Anvin 為首的核心開(kāi)發(fā)者引入 [
klibc
] 與 kinit,前者 (至少目標(biāo)上) 是最小的 C library 實(shí)做,用來(lái)支持後者所需 (定位與 [
dietlibc
] 或 [
uclibc
] 一類(lèi)精巧但通用性的 libc 實(shí)做不同),而 kinit 就是將前述原本在核心實(shí)做的程式 (很難偵錯(cuò)且分析的 kernel code) 拉出到 user-space 中,他於 2006 年六月提交的 patch [
kinit: replacement for in-kernel do_mount, ipconfig, nfsroot
]
就展現(xiàn)了將不同的檔案系統(tǒng) (cramfs, ext2, ext3, jfs, lvm2, minixfs, reiserfs, romfs,
xfs, ...) 予以?huà)燧d (即 user-space 的 do_mount)、ipconfig (bootp,
dhcp)、nfsmount 等等,整合到 kinit 程式中一併處理,kernel image 可因此大幅縮減。
大致理解
initramfs 的原理與定位後,我們就可以探討實(shí)做與相關(guān)的細(xì)節(jié)。筆者的測(cè)試環(huán)境是 IBM/lenovo X60 筆記型電腦 (Intel
Centrino Duo 1.83GHz) 加上 Ubuntu Linux 7.10,進(jìn)行下述實(shí)做過(guò)程之前,請(qǐng)先自 [
kernel.org
] 取得 stable kernel,本文採(cǎi)用 "linux-2.6.22.5",所需的套件有:
- build-essential
- qemu
- ruby
假設(shè)工作目錄為 $HOME/initramfs-workspace,作些準(zhǔn)備動(dòng)作:('$' 開(kāi)頭表示輸入的指令,以下同)
$ cd /home/jserv/initramfs-workspace
$ tar jxvf $HOME/sources/linux-2.6.22.5.tar.bz2
$ mkdir -p hello-initramfs
首先設(shè)立的目標(biāo)是,可印出 "Hello World" 的 kernel + initramfs,並透過(guò) qemu 進(jìn)行模擬驗(yàn)證。首先,建立一個(gè) init.c,具備簡(jiǎn)單的實(shí)做:
$ cd hello-initramfs
$ cat init.c
#include
int main()
{
printf("Hello World!\n");
sleep(99999);
return 0;
}
$ gcc -static -o init init.c
$ mkdir -p dev
$ sudo mknod dev/console c 5 1
建議先試著執(zhí)行 "./init" 看看是否正確運(yùn)作,程式碼中的 "sleep(99999)"
只是讓觀察更容易,避免畫(huà)面一閃而逝。剛剛的 "Hello World" 程式就是我們預(yù)期的 Early userspace,因?yàn)閳?zhí)行時(shí)期需要
tty (terminal),所以剛剛也一併建立 /dev/console 的 character device,F(xiàn)在我們可以來(lái)準(zhǔn)備建構(gòu)
kernel 了: $ cd /home/jserv/initramfs-workspace/linux-2.6.22.5
$ make menuconfig
要注意的是,需將 "General setup" 的子項(xiàng)目 "Initial RAM filesystem and RAM
disk (initramfs/initrd) suppot" 打開(kāi),並在下方提示 "INITRAMFS_SOURCE" 的畫(huà)面輸入我們期望的
initramfs 的來(lái)源目錄,也就是
"/home/jserv/initramfs-workspace/hello-initramfs",參考的配置畫(huà)面如下:
![]()
也可以參考筆者的組態(tài)檔 [
.config
],當(dāng)然之後就是建構(gòu)核心:
$ make bzImage
...
LD arch/i386/boot/compressed/vmlinux
OBJCOPY arch/i386/boot/vmlinux.bin
HOSTCC arch/i386/boot/tools/build
BUILD arch/i386/boot/bzImage
Kernel: arch/i386/boot/bzImage is ready
建構(gòu)成功,透過(guò) qemu 來(lái)模擬測(cè)試:
$ qemu -kernel arch/i386/boot/bzImage -hda /dev/zero
參考的執(zhí)行畫(huà)面如下:
![]()
所以我們可以發(fā)現(xiàn),在產(chǎn)生出來(lái)的 kernel image 中,其實(shí)已經(jīng)包含了剛剛的 initramfs,看來(lái)裡頭大有文章。回頭看看編譯的過(guò)程:
scripts/kconfig/conf -s arch/i386/Kconfig
CHK include/linux/version.h
CHK include/linux/utsrelease.h
CC arch/i386/kernel/asm-offsets.s
GEN include/asm-i386/asm-offsets.h
...
CC init/initramfs.o
CC init/calibrate.o
LD init/built-in.o
HOSTCC usr/gen_init_cpio
GEN usr/initramfs_data.cpio.gz
AS usr/initramfs_data.o
...
我們可注意到 "GEN usr/initramfs_data.cpio.gz" 這行,勢(shì)必 kernel 2.6 中隱含了某種機(jī)制,執(zhí)行看看之前產(chǎn)生的工具程式:
$ usr/gen_init_cpio
Usage:
usr/gen_init_cpio
is a file containing newline separated entries that
describe the files to be included in the initramfs archive:
...
這裡提到的 "archive" 就是透過(guò) [
cpio
] 工具產(chǎn)生的封裝檔案,在 RedHat .rpm 或 Debian .deb 均有採(cǎi)用此工具。不過(guò) Linux kernel 則提供一個(gè)整合性的工具,可一次處理目錄與檔案的封裝,依據(jù)之前的流程試試看手動(dòng)建立 cpio + gzip:
$ cd /home/jserv/initramfs-workspace
$ sudo cp -af hello-initramfs hello2-initramfs
$ cd hello2-initramfs
$ cat init.c
#include
int main()
{
printf("Yat Another Hello World!\n");
sleep(999999);
return 0;
}
$ gcc -static -o init init.c
$ cat desc_initramfs
dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1
file /init /home/jserv/initramfs-workspace/hello2-initramfs/init 0755 0 0
$ ../linux-2.6.22.5/usr/gen_init_cpio desc_initramfs > my_initramfs.cpio
$ gzip my_initramfs.cpio
"desc_initramfs" 是我們自己寫(xiě)的描述檔,格式大抵就如上面展示,usr/gen_init_cpio
這個(gè)工具則會(huì)建構(gòu)對(duì)應(yīng)的 dir + device node + file 的封裝,最後我們以 gzip 壓縮起來(lái),於是可得到
"my_initramfs.cpio.gz" 這個(gè)新的 initramfs image。同樣的,我們可用 qemu 測(cè)試驗(yàn)證,這次改由
qemu 模擬 boot loader 指定 initramfs image 的模式,操作如下: $ cd /home/jserv/initramfs-workspace/linux-2.6.22.5
qemu -kernel arch/i386/boot/bzImage -initrd ../hello2-initramfs/my_initramfs.cpio.gz -hda /dev/zero
這次應(yīng)該就會(huì)在 qemu 模擬的輸出畫(huà)面最下方看到 "Yat Another Hello World!" 的字樣。
只有 "Hello World" 一類(lèi)的程式只能作切入點(diǎn),還不能實(shí)際作點(diǎn)事情,從零到有建構(gòu) rootfs 也得花上一點(diǎn)功夫,還好,Ubuntu/Debian 已經(jīng)提供靜態(tài)連結(jié)的 [
BusyBox
],安裝方式很簡(jiǎn)單:
$ sudo apt-get install busybox-static
隨後,系統(tǒng)會(huì)安裝 /bin/busybox 的執(zhí)行檔,觀察一下:
$ file /bin/busybox
/bin/busybox: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, statically linked, stripped
咱們就以此為基礎(chǔ),建立一個(gè)小而美的 initramfs + kernel image:
$ cd /home/jserv/initramfs-workspace
$ mkdir -p busybox-initramfs/bin
$ mkdir -p busybox-initramfs/proc
$ cd busybox-initramfs/bin
$ cp /bin/busybox .
$ ./busybox --help | ruby -e 'STDIN.read.split(/functions:$/m)[1].split(/,/).each{|i|`ln -s busybox #{i.strip}` unless i=~/busybox/}'
$ cd ..
$ echo -e '#!/bin/busybox sh\nmount -t proc proc /proc\nexec busybox sh\n' > init ; chmod +x init
$ find . | cpio -o -H newc | gzip > ../busybox.initramfs.cpio.gz
可看到 $HOME/initramfs-workspace 就輸出了名為 busybox.initramfs.cpio.gz 的 initramfs image,可仿造上一個(gè)範(fàn)例,透過(guò) qemu 模擬:
$ cd /home/jserv/initramfs-workspace/linux-2.6.22.5
qemu -kernel arch/i386/boot/bzImage -initrd ../busybox.initramfs.cpio.gz -hda /dev/zero
參考的執(zhí)行畫(huà)面如下:
![]()
後續(xù)的篇幅,我們會(huì)探討實(shí)務(wù)上如何應(yīng)用,如 Ubuntu 的 software suspend/resume image 與 fast-booting 整合,以及 kernel 的實(shí)做細(xì)節(jié)。
本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u2/75200/showart_1729616.html |
|