原文地址:http://www.arm9home.net/simple/index.php?t5645.html 前天做了個從ramdisk根檔案系統啟動Linux的實驗,寫了個文章。經總版主kasim大俠的提攜,得知現在基於Linux的發行版通常採用initramfs代替initrd,架構更簡單,應用也更靈活一些。正好今天晚上沒事,就做了一下使用initramfs啟動Linux,寫個文章總結一下。
這個文章不會詳述具體的每一個步驟,僅僅說明它和使用ramdisk啟動系統時所需要做的步驟的區別。事實上我也是在前天配置編譯核心使用ramdisk啟動系統的步驟的基礎上改的。這裡只總結使用initramfs和使用ramdisk各自配置核心選項的主要區別和遇到的一些問題。
參照我的另一個文章《從ramdisk根檔案系統啟動Linux成功,總結一下》
http://www.arm9home.net/read.php?tid-5610.html
開發環境:Fedora 9
交叉編譯工具鏈:arm-linux-gcc 4.3.2 with EABI
嵌入式Linux核心版本:2.6.29.4-FriendlyARM。本文就是友善之臂的2.6.29.4-FriendlyARM的那個版本config_mini2440_t35的核心的基礎上改的。其它版本的應該也類似,僅供參考。
開發板:mini2440-128M Nand Flash
Bootloader:u-boot-2009.11
主要的不同點:
步驟2.修改核心配置選項
進入核心源碼目錄linux-2.6.29目錄
#cp config_mini2440_t35 .config
#make menuconfig ARCH=arm
開啟配置菜單,配置使用ramdisk啟動系統時需要設定兩個選項,這裡只需要配置一個配置項:
General setup-->選擇 Initial RAM filesystem and RAM disk...... 項
原因很簡單,我們使用的是initramfs,而不是ramdisk,所以不用配置ramdisk的驅動支援項Device Drivers-->Block devices-->RAM block device support 項。相應的之後的(4096)Default RAM disk size kbytes等相關預設配置選項就不會再出現了。
另外 initramfs技術和ramdisk技術的另一個重要的區別就是initramfs並不是在記憶體中類比出一個磁碟,所以也就不在需要ramdisk中所需的ext2驅動支援。所以,File systems菜單下的ext2檔案系統支援< > Second extended fs support選項就可以取消了。
在這一步還有一個重要的區別就是需要在General setup-->Initial RAM filesystem and RAM disk...... 項的相關項目(/work/rootfs) Initramfs source file(s)中填寫你要製作成initramfs格式的根檔案系統目錄,在這裡我要做的根檔案系統的目錄是/work/rootfs。
步驟6.製作initramfs根檔案系統
h)製作initramfs根檔案系統鏡像
製作最小系統根檔案系統的步驟和以前製作ramdisk根檔案系統的步驟基本一致,這裡只說明最後一步有何不同。
因為initramfs根檔案系統啟動時執行的第一個程式是init,而不是linuxrc,所以在此,我們製作的根檔案系統需要添加一個init檔案,相應的linuxrc檔案就不再需要了。
按照如下方式修改根檔案系統
#cd /work/rootfs
#ln -s bin/busybox init
這樣就為busybox建立了一個軟連結init,這個檔案就是我們要建立的init檔案。
另外就是我們製作ramdisk根檔案系統鏡像的時候使用的是genext2fs工具,在此我們製作initramfs根檔案系統鏡像時,並不需要額外的步驟,而是在你編譯Linux核心的時候就自動產生了。自動產生的initramfs根檔案系統鏡像在Linux源碼樹的usr目錄下。名字叫initramfs_data.cpio.gz,它是gz格式的壓縮檔。
這樣就有一個問題,在編譯可以使用initramfs啟動的核心的時候,它的配置選項有一個相關項目,就是要在(/work/rootfs) Initramfs source file(s)中填寫你要製作成initramfs格式的根檔案系統目錄。這樣就要求我們在編譯核心的時候,首先先把根檔案系統做好。值得注意的是我們按照這個方法製作出來的核心鏡像實際上比原來的大了許多,這是因為我們在做這一步的時候,實際上是將initramfs根檔案系統直接合并到核心鏡像裡邊了。這樣,合二為一的鏡像就不再需要單獨燒寫根檔案系統鏡像了,相應的,啟動核心時的參數就不需要添加initrd=……來指定initramfs的位置了。當然如果你不想將initramfs合并到核心中,直接用配置ramdisk的核心來啟動系統即可,不過這時你就必須使用initrd=……來指定 initramfs的位置了,並且第二個參數initramfs根檔案系統映像的大小必須指定為實際大小,否則提示映像校正錯誤,無法啟動系統。
其它的就沒有區別了。
-------------------------------------------------------------------
一切工作做好了,uImage和initramfs_data.cpio.gz都已經編譯出來了。
用u-boot下載核心鏡像和initramfs根檔案系統鏡像,此時啟動系統,最終核心恐慌kernel panic啟動失敗。
在超級終端的最後一行顯示錯誤如下:
Unpacking initramfs...<0>Kernel panic - not syncing: bad gzip magic numbers
上網查閱了相關的錯誤,解決方案如下:
“這個問題已經解決;
是因為,我在u-boot傳遞給核心的initrd=bufptr,size;
size這個參數中,大小比實際的initramfs的大小還大;
導致unpack_to_rootfs在調用gunzip進行initramfs壓縮包進行解壓時,gunzip無法判斷到initramfs壓縮包的結束位址;進行重複的解 壓導致的;(gunzip這個東東真不智能啊,呵呵)
將size設定和initramfs壓縮包的大小一致就OK了;”
如法炮製,系統啟動成功。