下面兩篇文章是ARM9論壇上的講解ramdisk文件系統的很不錯的文章php
今天作了個試驗,讓Linux2.6.29.4從ramdisk根文件系統啓動成功,總結一下。html
其中涉及的內容較多,不少東西再也不詳述,如需深刻研究請查閱相關資料(百度或谷歌一下一大堆)。
開發環境:Fedora 9
交叉編譯工具鏈:arm-linux-gcc 4.3.2 with EABI
嵌入式Linux內核版本:2.6.29.4-FriendlyARM。昨天寫貼子的時候具體記不清了,今天起來啓動開發板用uname -r查一下,就是叫作2.6.29.4-FriendlyARM,帖子已經改好了。本文就是友善之臂的2.6.29.4-FriendlyARM的那個版本的內核的基礎上改的。其它版本的應該也相似,僅供參考。
開發板:mini2440-128M Nand Flash
Bootloader:u-boot-2009.11
具體步驟以下:
1.解壓內核源碼樹
解壓linux-2.6.29-mini2440-20090708.tgz到本身的工做目錄,會生成一個友善之臂修改過的而且有幾個mini2440默認配置文件的內核源碼目錄linux-2.6.29。具體步驟參照友善之臂mini2440開發板用戶手冊,具體不詳述了。
2.修改內核配置選項
進入內核源碼目錄linux-2.6.29目錄
#cp config_mini2440_t35 .config
#make menuconfig ARCH=arm
打開配置菜單,修改兩個配置項,分別是:
a):General setup-->選擇 Initial RAM filesystem and RAM disk...... 項
b):Device Drivers-->Block devices-->選擇 RAM block device support 項
並檢查Optimize for size是否被選中,若是沒有則選中,此項優化內核大小,根據須要進行配置。
修改(8192)Default RAM disk size kbytes選項爲
(4096)Default RAM disk size kbytes,之因此修改是由於我以後製做的ramdisk是4096KB大小的。固然若是你想製做8192KB大小的ramdisk,這裏就要對應爲8192了,以此類推。可是最小系統嘛,是不用那麼大的ramdisk的。此項的默認配置就是(4096),之前我改過這個配置,因此是(8192)了。若是這個大小和你作的ramdisk不匹配,則啓動時仍然會出現kernel panic內核恐慌,提示ramdisk格式不正確,掛載不上ramdisk。
而後特別要注意的一點是,ramdisk是一種內存虛擬磁盤技術,實質上並非一種文件系統,它使用的文件系統時ext2文件系統。因此必定要在make menuconfig ARCH=arm的時候進入File systems菜單,選上<*> Second extended fs support。以提供內核對ext2文件系統的支持。我之前添加過了ext2文件系統了,因此開始的時候在此沒有說明,在此爲了說明爲何有的人照着個人方法作了,可是仍然kernel panic,特別把這一步也加上。
而後保存配置退出。
這樣就爲內核添加好了ramdisk啓動功能和ramdisk的驅動支持了。
3.修改內核啓動參數
方法有二:
a):修改.config的第310行,修改CONFIG_CMDLINE=""的定義
修改成CONFIG_CMDLINE="initrd=0x31000000,0x200000 root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64M"
保存。
意思爲從ramdisk啓動,ramdisk壓縮文件起始地址在內存地址0x31000000處,文件大小爲0x200000。
此參數也能夠在make menuconfig ARCH=arm時進入Boot options菜單,而後在Default kernel command string裏修改。效果是同樣的。
b):或者不修改.config的的第310行CMDLINE定義,而是用u-boot的bootargs環境變量來傳遞啓動參數。
一樣也是修改該環境變量爲bootargs=initrd=0x31000000,0x200000 root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64M
並saveenv保存u-boot環境變量
以上a),b)的效果是同樣的。
4.編譯內核
#make zImage ARCH=arm CROSS_COMPILE=arm-linux-
而後是二十分鐘左右的等待。
編譯完成後在當前目錄下就出現了zImage內核映像了。
好像友善之臂把內核源碼目錄裏的uImage目標給註釋了,之前在論壇裏看到過有人說,直接make uImage好像提示沒有uImage的目標。因此我就先製做zImage,而後再用u-boot的mkimage工具轉化爲uImage。其實uImage就是在zImage的開頭部分增長了一個64字節的內核映像說明。說明一下:zImage是ARM Linux經常使用的一種壓縮映像文件,uImage是U-boot專用的映像文件,它是在zImage以前加上一個長度爲0x40的「頭」,說明這個映像文件的類型、加載位置、生成時間、大小等信息。換句話說,若是直接從uImage的0x40位置開始執行,zImage和uImage沒有任何區別。另外,Linux2.4內核不支持uImage,Linux2.6內核加入了不少對嵌入式系統的支持,可是uImage的生成也須要設置。linux
5.製做uImage內核映像
因爲我使用的Bootloader是u-boot,因此要將zImage轉化爲uImage,方法以下:
#mkimage -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -n "Linux kernel Image" -d zImage uImage-ramdisk
說明:mkimage工具是u-boot格式uImage內核映像製做工具。若是成功編譯u-boot以後,它會在u-boot源碼樹下的tools目錄之下。建議將其拷貝到宿主機的/sbin/目錄下,以方便使用。mkimage使用時的具體參數再也不詳述,不清楚的請本身查閱。
6.製做ramdisk根文件系統(其實是創建根文件系統)
該過程是製做ramdisk根文件系統的核心步驟,方法以下:
a)建立根文件系統目錄:
#cd轉入到你的工做目錄。
#mkdir rootfs
#cd rootfs
#mkdir bin dev etc lib proc sbin sys usr mnt tmp var
#mkdir usr/bin usr/lib usr/sbin lib/modules
b)建立最基本的設備文件:
#cd dev
#mknod -m 666 console c 5 1
#mknod -m 666 null c 1 3
#cd ..
c)安裝/etc配置文件:
這裏能夠直接把友善之臂的root_qtopia裏的幾個基本的配置文件拷貝過來,只拷貝必要的便可,並對其內容進行刪減,由於我作的ramdisk並不包含Qtopia等,全拷貝過來也沒有用。
我是從網上找的最小系統的etc配置文件直接解壓到我製做的根文件系統裏了,並作參照友善之臂的root_qtopia添加了一些內容,見最後的說明。
操做以下:
#tar etc.tar.gz -C /xxx/rootfs
xxx表示你要製做的rootfs所在的目錄。
d)編譯內核模塊:
方法是以下:
進入Linux內核源碼目錄(linux-2.6.29)
#make modules ARCH=arm CROSS_COMPILE=arm-linux-
e)安裝內核模塊:
#make modules_install ARCH=arm INSTALL_MOD_PATH=/xxx/rootfs//嵌入式中的內核模塊都要在文件系統中
xxx表示你要製做的rootfs所在的目錄。
f)配置busybox
進入busybox目錄執行#make menuconfig
進入Busybox Settings -> build Options ->選中"Build busybox as a static binary「,即靜態連接,免去拷貝大量的庫文件。
Installation Options -> 選中"Don't use /usr",以避免busybox不慎被安裝到宿主機系統的相應目錄下,破壞宿主機系統。
Busybox Installation Prefix (/xxx/rootfs),修改該選項代表編譯後的busybox將安裝到該位置。
g)編譯、安裝busybox
#make ARCH=arm CROSS_COMPILE=arm-linux-
幾分鐘編譯完成後
#make install
安裝到Busybox Installation Prefix (/xxx/rootfs)設定的目錄裏。當前爲我要製做的根文件系統目錄(/xxx/rootfs)。
//完成根文件系統的建立
h)製做ramdisk根文件系統鏡像
方法以下:
上
http://genext2fs.sourceforge.net/下載能夠簡單方便的製做ramdisk文件系統的工具genext2fs,這樣就不用像網上大多數說的那樣繁瑣的製做ramdisk映像了,當前最新版本爲genext2fs-1.4.1.tar.gz 。
編譯生成該工具genext2fs,並將其放入宿主機的/sbin/目錄下以方便使用。
跳轉到要製做的rootfs的上一級目錄
#genext2fs -b 4096 -d rootfs ramdisk
-b是指製做的ramdisk大小爲4096K字節
-d是指要製做成ramdisk的根文件系統目錄
最後的ramdisk是製做出來的ramdisk的名字,固然能夠更名了。
#gzip -9 -f ramdisk
將該ramdisk以最優方式壓縮爲ramdisk.gz
7.下載內核映像和ramdisk映像
啓動u-boot,暫停u-boot自動啓動,在u-boot命令行中鍵入以下命令下載內核和ramdisk映像:
[u-boot@MINI2440]# tftp 0x32000000 uImage-ramdisk
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.31.117; our IP address is 192.168.31.230
Filename 'uImage-ramdisk'.
Load address: 0x32000000
Loading: T T #################################################################
#################################################################
#
done
Bytes transferred = 1917752 (1d4338 hex)
[u-boot@MINI2440]# tftp 0x31000000 ramdisk.gz
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.31.117; our IP address is 192.168.31.230
Filename 'ramdisk.gz'.
Load address: 0x31000000
Loading: T T #################################################################
####
done
Bytes transferred = 1002594 (f4c62 hex)
8)使用ramdisk根文件系統啓動內核
在u-boot命令行下鍵入以下命令啓動系統:
bootm 0x32000000
## Booting kernel from Legacy Image at 32000000 ...
Image Name: Linux-2.6.29.4-FriendlyARM
Created: 2010-04-09 15:13:52 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1917688 Bytes = 1.8 MB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux.............................................................
................................................................ done, booting t
he kernel.
Linux version 2.6.29.4-FriendlyARM (
root@localhost.localdomain) (gcc version 4.3
.2 (Sourcery G++ Lite 2008q3-72) ) #3 Fri Apr 9 23:13:36 CST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: FriendlyARM Mini2440 development board
Memory policy: ECC disabled, Data cache writeback
……中間過長的內容在此省略了……
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem) on device 1:0.
Freeing init memory: 136K
eth0: link down
Processing /etc/profile... Done
# eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
至此係統啓動成功。
----------------------------------------------------------------------------------
後記:因爲友善之臂mini2440默認的配置文件是將驅動等直接編譯到內核裏去了,並無使用內核模塊。因此上述第6步製做根文件系統中的d)編譯和e)安裝內核模塊的步驟能夠不作。我就沒有編譯內核模塊。由於參照友善之臂的root_qtopia根文件系統發現/lib/modules/`uname -r`里根本沒有東西。並且之前用友善之臂的config_mini2440_t35默認配置編譯內核模塊的時候。發現友善只作了個hello_modules的內核模塊示例。在此咱們不須要使用這個hello_modules,因此這兩步就略過去了。
說明:因爲最小系統裏的etc配置文件沒有寫自動啓動網卡的腳本,因此我作的ramdisk開始時並不能自動啓動網卡。後來參照友善之臂的root_qtopia根文件系統裏的腳本作以下修改,便可自動啓動腳本。
修改以下:
修改要製做的ramdisk根文件系統的rootfs下的/etc/init.d/rcS文件
在最下邊添加以下兩行命令便可自動啓動網卡:
/sbin/ifconfig lo 127.0.0.1
/sbin/ifconfig eth0 192.168.31.230 netmask 255.255.255.0 up
這個方法是經過分析友善之臂的root_qtopia根文件系統的啓動流程時發現的。
經過分析友善之臂的root_qtopia根文件系統,咱們還能發現更多的內容。在此不在詳述。
鍛鍊一下本身分析解決問題的能力吧。呵呵。架構
使用initramfs啓動Linux成功,再次總結一下
前天作了個從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了;」
如法炮製,系統啓動成功。