黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

深入理解 Linux 2.6 的 initramfs 機制 (上)

系統(tǒng) 2384 0

http://blog.linux.org.tw/~jserv/archives/001954.html

因為評論也很精彩,我一道轉(zhuǎn)來了

深入理解 Linux 2.6 的 initramfs 機制 (上)
日前結(jié)束一個消費性電子產(chǎn)品的開發(fā)工作,稍有心得,試著整理採取 Linux kernel 2.6 initramfs 機制以加速系統(tǒng)開發(fā)的經(jīng)驗,同時也談?wù)搶?fast-booting 設(shè)計的重要性,順便解決某些像是「kinit/klibc 為何被提出?」等疑難雜癥。

進入主題前,先看看所謂的 booting。相傳在十八世紀(jì),德國 Baron Münchhausen 男爵常誇大吹噓自己的英勇事蹟,其中一項是「拉著自己的頭髮,將自己從受陷的沼澤中提起」,此事後來收錄於德國《吹牛大王歷險記》,則改寫為「用拔靴帶把自己從海中拉起來」,這裡的「拔靴帶」(bootstrap) 指的是長統(tǒng)靴靴筒頂端後方的小環(huán)帶,是用以輔助穿長統(tǒng)靴。這種有違物理原理的誇大動作,卻讓不同領(lǐng)域的人們獲得靈感,Robert A. Heinlein 發(fā)表於 1941 年的短文〈By His Bootstraps〉收錄典故並給予多種延伸想法;滑鼠發(fā)明人 Doug Engelbart 博士甚至在 1989 年以此命名其研究機構(gòu)「Bootstrap 學(xué)院」,並擔(dān)任該院主任。在商業(yè)上,bootstrapping 則被引申為一種創(chuàng)業(yè)模式,也就是初期投入少量的啟動資本,然後在創(chuàng)業(yè)過程中主要依靠從客戶得來的銷售收入,形成一個良好的正現(xiàn)金流。在電腦資訊領(lǐng)域,因為開機過程是環(huán)環(huán)相扣,先透過簡單的程式讀入記憶體,執(zhí)行後又載入更多磁區(qū)、程式碼來執(zhí)行,直到作業(yè)系統(tǒng)完全載入為止,所以開機過程也被稱為 bootstrapping,簡稱 "boot"。

自 1991 年 Linux 問世以來,資訊技術(shù)的應(yīng)用有了極大的轉(zhuǎn)變,筆者之前的文章 [探索 Linux bootloader 的佳作] 與 [kboot 初探與模擬驗證] 約略提及光是開機本身的設(shè)計來說,就有多種衝擊與需求,隨著 Linux 走出個人電腦領(lǐng)域,在嵌入式系統(tǒng)應(yīng)用上,更是五花八門。本文所探討的 initramfs,衍生自 Linux kernel 的 initrd,理解其設(shè)計需求是先行的準(zhǔn)備。initrd 字面上的意思就是 "boot loader initialized RAM disk",換言之,這是一塊特殊的 RAM disk,在載入 Linux kernel 前,由 boot loader 予以初始化,具體動作就是從特定的儲存裝置中載入 initrd 到 RAM 中 (由啟動參數(shù) "initrd=" 指定 image 的實體或邏輯位置),隨後 linux kernel 被載入並執(zhí)行時,會優(yōu)先處理置放 initrd 的記憶體空間,而這個空間基本上也有檔案系統(tǒng),通常會包含 init 等程式,故可用以掛入某些特別的驅(qū)動程式,比方說 SCSI,完成階段性目標(biāo)後,kernel 會將真正的 root file system 掛載,並執(zhí)行 /sbin/init 程式。

話說回來,我們?yōu)楹涡枰说扔剞挼拈_機途徑呢?原因是,root file system (由啟動參數(shù) "root=" 所指定,以下簡稱 rootfs) 所在的儲存裝置很可能極難尋找,比方說 SCSI 裝置就需要複雜且耗時的程序,若用 RAID 系統(tǒng)更是需要看配置情況而定,同樣的問題也發(fā)生在 USB storage 上,因為 kernel 得花上更長的等待與配置時間,或說遠(yuǎn)端掛載 rootfs,不僅得處理網(wǎng)路裝置的問題,甚至還得考慮相關(guān)的伺服器認(rèn)證、通訊往返時間等議題。更重要的是,我們可在 initrd 放置某些特別的程式,一來作為掛載 rootfs 作準(zhǔn)備,比方說硬體初始化、解密、解壓縮等等,二來提示使用者或系統(tǒng)管理員目前的狀態(tài),這對於消費性電子產(chǎn)品來說,有很大的意義。整體來說,如果能增加開機的彈性 (比方說配合簡單的 shell script 即可達成 USB/SCSI 初始化動作,若透過 kernel code 實做,恐怕上百千行是免不掉的),又能適度降低 kernel image 本身的設(shè)計複雜度與空間使用量,採取 initrd 是很不錯的方式,所以幾乎各大 Linux distribution 都有提供 initrd,以解決在不同硬體、不同裝置上開機的技術(shù)議題,也能確保一片 CD-ROM/DVD 可裝入多種個人電腦系統(tǒng),也可支援 [bootsplash] 一類顯示開機動畫的程式。

具體來說,initrd 提供了「兩階段開機」程序。首先,一切都還是在 kernel mode,由 kernel 完成與硬體相關(guān)的初始化工作,接著,在適當(dāng)?shù)臅r機點,當(dāng) kernel 讀取並掛載 initrd 所在記憶體空間的檔案系統(tǒng)後,kernel 首次從 kernel space 切入 user space,以執(zhí)行存放於 RAM disk 中的 init 程式,當(dāng)然,這需要完整的執(zhí)行環(huán)境 (比方說 C runtime 或必要的 program loader 等),另外,也得確定 rootfs 可被 kernel 所找到並正確掛載。待第一階段的 initrd 步入尾聲後,再回到 kernel mode,initrd 所在的記憶體空間也會適度被釋放 (依據(jù)組態(tài)而定),這才進入第二階段,也就是執(zhí)行真正的 rootfs 中的 init 程式。在 Linux kernel 2.4 中,initrd 大致的處理流程如下:(方括號表示主要的執(zhí)行單元)
[boot loader] Boot loader 依據(jù)預(yù)先設(shè)定的條件,將 kernel 與 initrd 這兩個 image 載入到 RAM
[boot loader -> kernel] 完成必要的動作後,準(zhǔn)備將執(zhí)行權(quán)交給 Linux kernel
[kernel] 進行一系列初始化動作,initrd 所在的記憶體被 kernel 對應(yīng)為 /dev/initrd 裝置設(shè)備,透過 kernel 內(nèi)部的 decompressor (gzip 解壓縮) 解開該內(nèi)容並複製到 /dev/ram0 裝置設(shè)備上
[kernel] Linux 以 R/W (可讀寫) 模式將 /dev/ram0 掛載為暫時性的 rootfs
[kernel-space -> user-space] kernel 準(zhǔn)備執(zhí)行 /dev/ram0 上的 /linuxrc 程式,並切換執(zhí)行流程
[user space] /linuxrc 與相關(guān)的程式處理特定的操作,比方說準(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)用程式
值得一提的是,以上「兩階段開機」是 initrd 提出的彈性開機流程,在真實的應(yīng)用中,也可能從未需要掛載真正的 rootfs,換言之,只是把系統(tǒng)當(dāng)作都在 RAM disk 上運作,或者永遠(yuǎn)都在 initrd 所引導(dǎo)執(zhí)行的 /linuxrc 程序中執(zhí)行 (注意:kernel 永遠(yuǎn)保留 PID=1 作為 init process 識別,而 /linuxrc 執(zhí)行的 PID 必非為 1),在許多裝置如智慧型手機,都是行之有年的,不過這不影響我們後續(xù)的探討。

Linux Kernel 的發(fā)展文化就是願意捨棄既有實做,大膽採用新的途徑 (在符合國際規(guī)格的前提下),Linux 2.6 的 initramfs 之所以提出,就是要修正 initrd 的種種技術(shù)問題。問題在哪呢?首先,回顧剛剛探討的流程,initrd RAM disk 對 kernel 來說,本身是個真實的 block device,為了建構(gòu)存放其中的檔案 (最起碼要有 /linuxrc),通常我們需要 ext2 一類的檔案系統(tǒng) (建議)。所以,就建構(gòu)如此的 initrd image 來看,通常會透過 mkfs.ext2 與 losetup (功能:"set up and control loop devices") 等工具建立 loopback device 並編修,所以自然需面對以下問題:
initrd 必須綁定某個檔案系統(tǒng)實做,如 ext2,可是多數(shù)的情況下,我們根本不需要在此階段擁有完整的實做
/dev/initrd block device 建構(gòu)時即有空間限制,維護繁瑣
運作於 initrd 階段,檔案操作實際上是不斷將 /dev/initrd (對應(yīng)於某段記憶體) 對應(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 的提出,則是基於更簡單有效率的 ramfs 與新的處理方式。

回到 initrd ramdisk,事實上,原本的設(shè)計甚至更加浪費記憶體,因為 Linux 在設(shè)計上就會盡可能將讀入/寫入自 block device 的檔案或目錄予以 cache,所以,Linux 會自 ramdisk 中複製資料到 page cache 與 dentry cache,如此往返,徒增資源使用的浪費,這一切問題的根源就是將 initrd 以 block device 來操作的本質(zhì)使然。Linus Torvalds 為此提出一個想法:
能否將這些 cache 被掛載為檔案系統(tǒng)呢?就在 cache 中保持這些檔案,但不清除這些,直到實際上被刪去或者系統(tǒng)重啟。
基於這些想法,Linus Torvalds 實做了 ramfs,隨後在其他核心開發(fā)者的改進下,成為 tmpfs,支援寫入 swap 空間與限制記憶體使用量等特徵。而,initramfs 就是建構(gòu)於 tmpfs 的基礎(chǔ)上。採取此途徑的效益就是,檔案系統(tǒng)可自行調(diào)整空間使用量,以符合所需資料儲存的空間,同時,也不再會有重複的 block device 與 cache 資料,因為跟本不需要,更重要的是,這樣的檔案系統(tǒng)實做,其實就只是 cache 機制的延伸,沒有太多新的程式碼,所以系統(tǒng)可保持簡單明暸。以下是對 initrd 與 initramfs 的概念性比較:??? initrd??? initramfs
Image??? 壓縮過的檔案系統(tǒng) (如 ext2 + gzip)??? 封裝過的檔案 (cpio + gzip)
實做途徑??? block device (RAM disk)??? tmpfs
首先執(zhí)行的程式??? /linuxrc??? /init
掛載
rootfs 方式??? 將欲載入的 rootfs 掛載於某個目錄,再 pivot_root 切換 rootfs??? 使用 switch_root

前面的段落已說明這兩者對於記憶體存取與檔案操作的落差,同時也提及實做途徑,接下來的重點是這兩者如何看待真正的 rootfs。如同前述所及,Linux kernel 2.4 中,initrd 可被視為起始參數(shù) "root=" 的先前處理機制,透過一系列的程序,協(xié)助 kernel 找到最終的 rootfs,並一舉掛載進系統(tǒng),不過,過去的設(shè)計其實做了一個假設(shè):「真正的 rootfs 所在的裝置是 block device,同時 initrd 絕非是真正的 rootfs」,這也是為何要讓 kernel 在第一次準(zhǔn)備切入 user-space 時,是執(zhí)行 /linuxrc,而非 /init 或 /sbin/init,因為後者的 PID 恆為 1 且不可被 kill (終止),但前者因為只是過度的存在,隨時仍可被 kill。

而在 Linux 2.6 引入 initramfs 的設(shè)計後,上述彆扭的假設(shè)與處理方式就不復(fù)存在,不再區(qū)隔「真正」的 rootfs 是如何「存在」,也就是一開機,kernel 就執(zhí)行位於 initramfs 中的 /init,作為 PID=1 的 init process,僅以 switch_root 作 rootfs 的重新定位罷了 (選擇性)。正因為這樣的特性,核心開發(fā)者也將 initramfs 的行為稱為 [Early User Space],Jeff Garzik 於 2002 年十一月發(fā)表於 lkml 的文章 [initramfs merge, part 1 of 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.
核心開發(fā)者很喜歡彼此取笑,這裡提到的 [Al Viro] 是位知名的 kernel hacker,常常為了捍衛(wèi)核心設(shè)計的一致性與許多開發(fā)者對立。這意思就是說,藉由 Early userspace 整合到核心設(shè)計後,原本很不容易處理的開機模式,比方說 LVM (Linux Volume Manager)、網(wǎng)路開機、特別儲存裝置的開機等,都可交由 user-space 的應(yīng)用程式專門處理,相對來說,kernel 就不必過度涉入,長遠(yuǎn)來說,對於發(fā)展的分工、降低系統(tǒng)複雜度,以及提高可性賴度,均有很大的助益。

基於 initramfs / Early userspace 的想法,核心開發(fā)者又思考為何不將過去難以有效維護但又非得存在不可的程式碼,比方說 do_mount 這一類用以實做掛載特定裝置或邏輯儲存設(shè)備的功能,全面轉(zhuǎn)交給 user-space 的程式去執(zhí)行呢?這樣 kernel 可專心提昇功能或者效能的改進。為此,以 H. Peter Anvin 為首的核心開發(fā)者引入 [klibc] 與 kinit,前者 (至少目標(biāo)上) 是最小的 C library 實做,用來支持後者所需 (定位與 [dietlibc] 或 [uclibc] 一類精巧但通用性的 libc 實做不同),而 kinit 就是將前述原本在核心實做的程式 (很難偵錯且分析的 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, ...) 予以掛載 (即 user-space 的 do_mount)、ipconfig (bootp, dhcp)、nfsmount 等等,整合到 kinit 程式中一併處理,kernel image 可因此大幅縮減。

大致理解 initramfs 的原理與定位後,我們就可以探討實做與相關(guān)的細(xì)節(jié)。筆者的測試環(huán)境是 IBM/lenovo X60 筆記型電腦 (Intel Centrino Duo 1.83GHz) 加上 Ubuntu Linux 7.10,進行下述實做過程之前,請先自 [kernel.org] 取得 stable kernel,本文採用 "linux-2.6.22.5",所需的套件有:
build-essential
qemu
ruby
假設(shè)工作目錄為 $HOME/initramfs-workspace,作些準(zhǔn)備動作:('$' 開頭表示輸入的指令,以下同)
$ 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,並透過 qemu 進行模擬驗證。首先,建立一個 init.c,具備簡單的實做:
$ cd hello-initramfs
$ cat init.c
#include <stdio.h>
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" 看看是否正確運作,程式碼中的 "sleep(99999)" 只是讓觀察更容易,避免畫面一閃而逝。剛剛的 "Hello World" 程式就是我們預(yù)期的 Early userspace,因為執(zhí)行時期需要 tty (terminal),所以剛剛也一併建立 /dev/console 的 character device。現(xiàn)在我們可以來準(zhǔn)備建構(gòu) kernel 了:
$ cd /home/jserv/initramfs-workspace/linux-2.6.22.5
$ make menuconfig
要注意的是,需將 "General setup" 的子項目 "Initial RAM filesystem and RAM disk (initramfs/initrd) suppot" 打開,並在下方提示 "INITRAMFS_SOURCE" 的畫面輸入我們期望的 initramfs 的來源目錄,也就是 "/home/jserv/initramfs-workspace/hello-initramfs",參考的配置畫面如下:

也可以參考筆者的組態(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)成功,透過 qemu 來模擬測試:
$ qemu -kernel arch/i386/boot/bzImage -hda /dev/zero
參考的執(zhí)行畫面如下:

所以我們可以發(fā)現(xiàn),在產(chǎn)生出來的 kernel image 中,其實已經(jīng)包含了剛剛的 initramfs,看來裡頭大有文章。回頭看看編譯的過程:
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" 這行,勢必 kernel 2.6 中隱含了某種機制,執(zhí)行看看之前產(chǎn)生的工具程式:
$ usr/gen_init_cpio
Usage:
??? usr/gen_init_cpio <cpio_list>

<cpio_list> is a file containing newline separated entries that
describe the files to be included in the initramfs archive:
...
這裡提到的 "archive" 就是透過 [cpio] 工具產(chǎn)生的封裝檔案,在 RedHat .rpm 或 Debian .deb 均有採用此工具。不過 Linux kernel 則提供一個整合性的工具,可一次處理目錄與檔案的封裝,依據(jù)之前的流程試試看手動建立 cpio + gzip:
$ cd /home/jserv/initramfs-workspace
$ sudo cp -af hello-initramfs hello2-initramfs
$ cd hello2-initramfs
$ cat init.c
#include <stdio.h>
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" 是我們自己寫的描述檔,格式大抵就如上面展示,usr/gen_init_cpio 這個工具則會建構(gòu)對應(yīng)的 dir + device node + file 的封裝,最後我們以 gzip 壓縮起來,於是可得到 "my_initramfs.cpio.gz" 這個新的 initramfs image。同樣的,我們可用 qemu 測試驗證,這次改由 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)該就會在 qemu 模擬的輸出畫面最下方看到 "Yat Another Hello World!" 的字樣。

只有 "Hello World" 一類的程式只能作切入點,還不能實際作點事情,從零到有建構(gòu) rootfs 也得花上一點功夫,還好,Ubuntu/Debian 已經(jīng)提供靜態(tài)連結(jié)的 [BusyBox],安裝方式很簡單:
$ sudo apt-get install busybox-static
隨後,系統(tǒng)會安裝 /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ǔ),建立一個小而美的 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,可仿造上一個範(fàn)例,透過 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í)行畫面如下:

後續(xù)的篇幅,我們會探討實務(wù)上如何應(yīng)用,如 Ubuntu 的 software suspend/resume image 與 fast-booting 整合,以及 kernel 的實做細(xì)節(jié)。
由 jserv 發(fā)表於 January 20, 2008 11:54 PM
迴響

哇,這一篇對小型Linux系統(tǒng)的開發(fā)者大有幫助。
由 checko 發(fā)表於 January 21, 2008 12:16 AM

$ 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

也許可以改成

$ cp /bin/busybox .
$ cd ..
$ echo -e '#!/bin/busybox sh\n/bin/busybox --install\nmount -t proc proc /proc\nexec busybox sh\n' > init ; chmod +x init

就不用 ruby 了~ 對初學(xué)者可能會更簡單~ :)
當(dāng)然 jserv 也許有效率上的考量
先建好就不用在 runtime 花時間建立
由 FourDollars 發(fā)表於 January 21, 2008 11:20 AM

To FourDollars,

Thanks. 不過一般我們看到 shell,就會不自覺想敲入 "ls" 一類的指令,所以本文先建立 symbolic links。話說回來,好像沒透過文字?jǐn)⑹觯杏X不太好。
由 jserv 發(fā)表於 January 21, 2008 02:36 PM

jserv 好~
去年也做了一些只用 initramfs 的系統(tǒng)~
由 華華 發(fā)表於 January 21, 2008 04:31 PM

很受教益,轉(zhuǎn)栽了,謝謝。
由 why 發(fā)表於 January 21, 2008 08:59 PM

前輩寫的好清楚喔,讓我這個沒概念的人大概了解了。

話說前幾天我的系統(tǒng)重開機後,在啟動的過程中出現(xiàn)「ERROR 15」,然後我進grub修改一些啟動參數(shù)發(fā)現(xiàn)在root=這邊是一串UUID識別碼,改完內(nèi)核版本及root目錄啟動後就出現(xiàn) busybox 的命令工具,它的提示符就是(initramfs)

為什麼root=後面會是UUID識別碼呢?

因為看的太仔細(xì)了XD,糾幾個錯字^^

>>而 /linuxrc 執(zhí)行的 PID 「必」非為 1

>「跟」本
由 yugu 發(fā)表於 January 22, 2008 03:02 AM

@yugu
你也可以 root=/dev/sda1 之類,
新的 linux 發(fā)行版默認(rèn)用 uuid 是為了更通用,
譬如下邊兩個情況:
1. 不同的驅(qū)動下 /dev 里的設(shè)備名字會不一樣,而 uuid 是唯一的。
2. 更換硬碟/磁盤或使用移動存儲的時候, /dev 下的設(shè)備名字也會不一樣, 而 uuid 是唯一的
由 華華 發(fā)表於 January 24, 2008 07:05 PM

感謝jserv大!

我跟著您的步驟做了之後,發(fā)現(xiàn)在x86_64上會有些問題
在使用自己產(chǎn)生的initrd會有問題
qemu上面秀的訊息是停在
It looks like a initrd.
然後就死在那邊了@@

不知是cpio那邊出問題還是...?
由 cyberj 發(fā)表於 January 30, 2008 02:59 PM

To cyberj,

請改用 qemu-system-x86_64 試試。
由 jserv 發(fā)表於 January 30, 2008 03:40 PM

To jserv,

我是用qemu-system-x86_64執(zhí)行的
不過我似乎沒有注意到更關(guān)鍵的提示
checking if image is initramfs... it isn't (bad gzip magic numbers); looks like an initrd
至於為什麼gzip會有問題,我就不清楚了XD

btw, 只要用第一個方法 make menuconfig
還是可以輕鬆地將busybox做成ramdisk^^

ps:用錯版本qemu的話,開機時會有提示
(我不確定是bootloader提示的,還是??)
由 cyberj 發(fā)表於 January 31, 2008 02:34 PM

To cyberj,

真有意思,所以我們發(fā)現(xiàn)了在 x86_64 平臺上,initramfs image 的生成可能有些許的差異。看來可能要追一下 kernel build 的細(xì)節(jié)了,感謝提醒!
由 jserv 發(fā)表於 January 31, 2008 03:51 PM

請教一下.
我用 allnoconfig, 有加上 ram block device, 也有設(shè) initramfs.
卻說找不到 /init.
why ?
由 jeunder 發(fā)表於 September 19, 2008 07:27 PM

自問自答.
因為沒有開 kernel support for ELF binaries.
ram block device 倒是可以不用開.
由 jeunder 發(fā)表於 September 19, 2008 09:08 PM

改成這樣的產(chǎn)生方式如何?

cd /home/jserv/initramfs-workspace
mkdir -p busybox-initramfs/{bin,proc,usr/{bin,sbin}}
cp /bin/busybox busybox-initramfs/bin
mount -t proc none busybox-initramfs/proc
chroot busybox-initramfs /bin/busybox sh
/bin/busybox --install -s

exit
umount busybox-initramfs proc

完全不使用 ruby, 直接產(chǎn)生 symbol links
由 dou0228 發(fā)表於 January 9, 2009 05:14 PM

謝謝博主
由 two536 發(fā)表於 February 8, 2009 02:02 PM

jserv 兄,這篇文章的(下)寫好沒有,很期待啊。
很期待你的“後續(xù)的篇幅”對“fast-booting”的探討。
由 chky 發(fā)表於 February 11, 2009 03:08 PM

看到最後才發(fā)現(xiàn)是 jserv 寫的..難怪條理清晰觀念清楚...(絕對不是拍馬屁)
由 sfc 發(fā)表於 March 6, 2009 10:17 AM

To cyberj,jserv
基本上jserv的做法無誤
問題在於以第二種方法, 必須精確地把initramfs.cpio.gz的檔案長度透過boot option傳入, 否則gunzip 會嘗試?yán)^續(xù) decode檔案之後的空間, 造成gzip 錯誤

try trace unpack_to_rootfs() in init/initramfs.c
由 網(wǎng)路黑貓 發(fā)表於 March 24, 2009 11:55 AM

深入理解 Linux 2.6 的 initramfs 機制 (上)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論