這幾天參考國嵌的實驗手冊和網上的資料完成了u-boot定製、核心定製、ramdisk根檔案系統的製作,並成功。趁熱打鐵,總結一下。本文引用了很多網路上的文章,就不一一註明了。感謝各大俠的協助,如有雷同,望見諒。
開發環境:紅帽企業版5
交叉編譯工具鏈:arm-linux-gcc4.3.2
嵌入式Linux核心版本:友善之臂的mini2440開發板光碟片內建的核心linux-2.6.32.2
開發板:mini2440-64MNand Flash
Bootloader:u-boot-1.20
具體步驟如下:
1.U-BOOT定製
因為內容較多,改天再總結一篇吧,在這先不多說
2.解壓核心源碼樹
具體步驟參照友善之臂mini2440開發板使用者手冊,具體不詳述了。
3.修改核心配置選項
make menuconfig,開啟配置菜單,修改兩個配置項,分別是:
a):General setup-->選擇 Initial RAM filesystem and RAM disk...... 項
b):DeviceDrivers-->Block devices-->選擇 RAM block devicesupport 項
修改(4920)Default RAM disk size kbytes選項為(8192)Default RAM disk size kbytes
特別要注意的一點是,ramdisk是一種記憶體虛擬磁碟技術,實質上並不是一種檔案系統,它使用的檔案系統時ext2檔案系統。所以一定要在make menuconfig的時候進入File systems菜單,選上<*>Second extended fs support。以提供核心對ext2檔案系統的支援。
然後儲存配置退出。
這樣就為核心添加好了ramdisk啟動功能和ramdisk的驅動支援了。
4.修改核心啟動參數
方法有二:
a):修改.config的第310行,修改"CONFIG_CMDLINE"的定義
修改為CONFIG_CMDLINE="initrd=0x32000000,0x200000root=/dev/ram rw console=ttySAC0 mem=64M" 儲存。
意思為從ramdisk啟動,ramdisk壓縮檔起始地址在記憶體位址0x32000000處,檔案大小為0x200000。
此參數也可以在makemenuconfig ARCH=arm時進入Boot options菜單,然後在Default kernel command string裡修改。效果是一樣的。
b):或者不修改.config的的第310行CMDLINE定義,而是用u-boot的bootargs環境變數來傳遞啟動參數。
同樣也是修改該環境變數為bootargs=initrd=0x31000000,0x200000root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64M
並saveenv儲存u-boot環境變數
以上a),b)的效果是一樣的。(註:我只試了a,b未試)
5.編譯核心
注意:好像友善之臂把核心源碼目錄裡的uImage目標給注釋了,直接makeuImage會提示沒有uImage的目標。zImage 是ARMLinux常用的一種壓縮映像檔案,uImage是U-boot專用的映像檔案,它是在zImage之前加上一個長度為0x40的“頭”,說明這個映像文 件的類型、載入位置、產生時間、大小等資訊。換句話說,如果直接從uImage的0x40位置開始執行,zImage和uImage沒有任何區別。另外,Linux2.4核心不支援uImage,Linux2.6核心加入了很多對嵌入式系統的支援,但是uImage的產生也需要設定。
在這裡,我直接把u-boot根目錄下/tools中的mkimage工具拷貝到主機的/usr/bin目錄下,就可以直接在核心根目錄下執行
#make uImageARCH=arm CROSS_COMPILE=arm-linux-
等待一會,核心編譯完成。
6.製作ramdisk根檔案系統(實際上是建立根檔案系統)
該過程是製作ramdisk根檔案系統的核心步驟,方法如下:
a)建立根檔案系統目錄:
#cd轉入到你的工作目錄。
#mkdir rootfs
#cd rootfs
#mkdir bin dev etclib proc sbin sys usr mnt tmp var
#mkdir usr/binusr/lib usr/sbin lib/modules
b)建立最基本的裝置檔案:
#cd dev
#mknod -m 666console c 5 1
#mknod -m 666 nullc 1 3
#cd ..
c)安裝/etc設定檔:
我是用的國嵌提供的etc設定檔,未作修改,直接解壓到根檔案系統裡。
操作如下:
#tar etc.tar.gz -C/xxx/rootwhj
xxx表示你要製作的根目錄所在路徑。
d)編譯核心模組:
進入Linux核心源碼根目錄
#make modulesARCH=arm CROSS_COMPILE=arm-linux-
e)安裝核心模組:
#makemodules_install ARCH=arm INSTALL_MOD_PATH=/xxx/rootwhj//嵌入式中的核心模組都要在檔案系統中
xxx表示你要製作的rootfs所在的目錄。
f)配置busybox
進入busybox目錄執行#make menuconfig
進入BusyboxSettings -> build Options ->選中"Build busyboxas a static binary“,即靜態連結,免去拷貝大量的庫檔案。
InstallationOptions -> 選中"Don't use /usr",以免busybox不慎被安裝到宿主機系統的相應目錄下,破壞宿主機系統。
BusyboxInstallation Prefix (/xxx/rootwhj),修改該選項表明編譯後的busybox將安裝到該位置。
g)編譯、安裝busybox
#make ARCH=arm CROSS_COMPILE=arm-linux-
幾分鐘編譯完成後
#make install
安裝到BusyboxInstallation Prefix (/xxx/rootwhj)設定的目錄裡。當前為我要製作的根檔案系統目錄(/xxx/rootwhj)。
//完成根檔案系統的建立
h)製作ramdisk根檔案系統鏡像
方法如下:
上http://genext2fs.sourceforge.net/下載可以簡單方便的製作ramdisk檔案系統的工具genext2fs,這樣就不用像網上大多數說的那樣繁瑣的製作ramdisk映像了,當前最新版本為genext2fs-1.4.1.tar.gz 。
編譯產生該工具genext2fs,並將其放入宿主機的/sbin/目錄下以方便使用。
跳轉到要製作的rootfs的上一級目錄
#genext2fs -b 8192-d rootfs ramdisk
-b是指製作的ramdisk大小為8MB
-d是指要製作成ramdisk的根檔案系統目錄
最後的ramdisk是製作出來的ramdisk的名字,當然可以改名了。
#gzip -9 -f ramdisk
將該ramdisk以最優方式壓縮為ramdisk.gz
7.下載核心映像和ramdisk映像
DRAM: 64 MB
Flash: 512 kB
In: serial
Out: serial
Err: serial
whj2440 # printenv
bootargs=root=ramfs devfs=mount console=ttySA0,9600
bootdelay=3
baudrate=115200
ethenv=00:01:02:03:04:05
filesize=1da248
fileaddr=32000000
netmask=255.255.255.0
ipaddr=202.205.85.164
serverip=202.205.85.165
stdin=serial
stdout=serial
stderr=serial
Environment size: 248/65532 bytes
whj2440 # tftp 31000000 uImage
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 00:80:00:80:00:80
TFTP from server 202.205.85.165; our IP address is 202.205.85.164
Filename 'uImage'.
Load address: 0x31000000
Loading: T #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#
done
Bytes transferred = 2329916 (238d3c hex)
whj2440 # tftp 32000000 ramdisk.gz
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 00:80:00:80:00:80
TFTP from server 202.205.85.165; our IP address is 202.205.85.164
Filename 'ramdisk.gz'.
Load address: 0x32000000
Loading: T #################################################################
#################################################################
#############################################
done
Bytes transferred = 891755 (d9b6b hex)
8.使用ramdisk根檔案系統啟動核心
whj2440 # bootm31000000
## Booting image at 31000000 ...
Image Name: Linux-2.6.32.2-ARMofWHJ
Created: 2011-09-06 22:48:18UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2329852 Bytes = 2.2 MB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
OK
Starting kernel ...
UncompressingLinux.............................................................
................................................................................
.......... done, booting the kernel.
Linux version 2.6.32.2-ARMofWHJ (root@localhost.localdomain) (gcc version 4.3.2
(Sourcery G++ Lite 2008q3-72) ) #17 Wed Sep 7 06:41:21 CST 2011
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: FriendlyARM Mini2440 development board
Warning: bad configuration page, trying to continue
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
中間過長,省略
RAMDISK: gzip image found at block 0
VFS: Mounted root (ext2 filesystem) on device 1:0.
Freeing init memory: 176K
Processing /etc/profile... Done
#
至此系統啟動成功。
-----------------------以下為引用------------------------------------------
後記:由 於友善之臂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 lo127.0.0.1
/sbin/ifconfig eth0192.168.31.230 netmask 255.255.255.0 up
這個方法是通過分析友善之臂的root_qtopia根檔案系統的啟動流程時發現的。
通過分析友善之臂的root_qtopia根檔案系統,我們還能發現更多的內容。在此不在詳述。
鍛煉一下自己分析解決問題的能力吧。呵呵。