操作系統(tǒng):Ubuntu9.04
內(nèi)核版本:linux-2.6.24.7
開發(fā)板:博創(chuàng)arm2410s
交叉編譯工具:arm-linux-gcc-4.1.1
BusyBox:busybox-1.11.1
CramFS:CramFS-1.1
注意:由于要制作的根文件系統(tǒng)使用了mdev(BusyBox簡化版的udev),因此,需要內(nèi) 核支持sysfs、procfs和ramfs(tmpfs)文件系統(tǒng)以及hotplug(uevent)事件機制。
淺藍(lán)色為命令,橘紅色為 代碼和腳步
1、準(zhǔn)備根文件系統(tǒng)
使用shell腳本create_rootfs.sh,建立根文件系統(tǒng)的目錄框架
lingd@ubuntu:~/arm2410s$ vi create_rootfs.sh
create_rootfs.sh 內(nèi)容如下:
#!/bin/sh
echo "------Create rootfs directons......"
mkdir rootfs
cd rootfs
echo "--------Create root,dev......"
mkdir root dev etc bin sbin mnt sys proc lib home tmp var usr
mkdir usr/sbin usr/bin usr/lib usr/modules
mkdir mnt/usb mnt/nfs mnt/etc mnt/etc/init.d
mkdir lib/modules
chmod 1777 tmp
cd ..
echo "-------make direction done---------"
為 create_rootfs.sh添加執(zhí)行權(quán)限
lingd@ubuntu:~/arm2410s$ chmod a+x create_rootfs.sh
執(zhí)行create_rootfs.sh,建立根文件系統(tǒng)的目錄框架
lingd@ubuntu:~/arm2410s$ ./create_rootfs.sh
lingd@ubuntu:~/arm2410s$ cd rootfs
lingd@ubuntu:~/arm2410s/rootfs$ ls
bin dev etc home lib mnt proc root sbin sys tmp usr var
2、創(chuàng)建設(shè)備 文件
mdev 是通過 init 進(jìn)程來啟動的,在使用 mdev 構(gòu)造 /dev 目錄之前,init 至少要用到設(shè)備文件/dev/console、 /dev/null ,所以需要事先建立這兩個設(shè)備文件:
lingd@ubuntu:~/arm2410s/rootfs$ cd dev
lingd@ubuntu:~/arm2410s/rootfs/dev$ sudo mknod -m 660 console c 204 64
[sudo] password for lingd:
lingd@ubuntu:~/arm2410s/rootfs/dev$ sudo mknod -m 660 null c 1 3
lingd@ubuntu:~/arm2410s/rootfs/dev$ ls -l
total 0
crw-rw---- 1 root root 5, 1 2010-04-02 15:49 console
crw-rw---- 1 root root 1, 3 2010-04-02 15:50 null
注意:本來console的主次設(shè)備號應(yīng)為5和1.但是因為init在執(zhí)行完/etc/init.d/rcS腳本后,就 會在一個控制臺上,按照inittab的指示開一個shell(或者是開getty+login,這樣用戶就會看到提示輸入用戶名的提示符)。在mdev -s未執(zhí)行之前,/dev目錄下只有我們創(chuàng)建的/dev/null和/dev/console,也就是說,沒有控制臺可供init用來按照inittab 的指示開一個shell。而在s3c24xx 系列芯片的串口驅(qū)動里面用了s3c2410_serial做為設(shè)備名(在內(nèi)核源碼的“drivers/serial/s3c2410.c”文件的949 行),因此,啟動時可用s3c2410_serial0、s3c2410_serial1或s3c2410_serial2作為init用來按照 inittab的指示開一個shell的控制臺,這里我用了串口0,即s3c2410_serial0(主次設(shè)備號為204和64)作為控制臺。這里直接 將console當(dāng)s3c2410_serial0,所以console的主次設(shè)備號才會為204和64。
3、準(zhǔn)備一些配置文件和系統(tǒng)啟動時所需的文件
3.1、mdev配置文件mdev.conf
mdev 會在/etc目錄下找mdev的配置文件: mdev.conf. 如果該文件不存在,那么在執(zhí)行mdev –s這個命令時,會提示找不到mdev.conf。我們不需要mdev規(guī)則,所以只是touch生成一個空文件就OK了。當(dāng)然也可以根據(jù)mdev的規(guī)則來 編寫mdev.conf。我把所有配置文件都是在/mnt/etc下,而不是/etc,后面解釋這么做的原因。
lingd@ubuntu:~/arm2410s/rootfs/dev$ cd ../mnt/etc
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ touch mdev.conf
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ ls
init.d mdev.conf
3.2、linuxrc
linuxrc 位于根文件系統(tǒng)的頂層目錄/,這里為rootfs。/Linuxrc 執(zhí)行init 進(jìn)程初始化文件。主要工作是把已安裝根文件系統(tǒng)中的/etc 安裝為ramfs,并拷貝/mnt/etc/目錄下所有文件到/etc,這里存放系統(tǒng)啟動后的許多特殊文件;接著Linuxrc 重新構(gòu)建文件分配表inittab;之后執(zhí)行系統(tǒng)初始化進(jìn)程/sbin/init。
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ cd ../..
lingd@ubuntu:~/arm2410s/rootfs$ vi linuxrc
linuxrc 內(nèi)容如下:
#!/bin/sh
echo "Processing /linuxrc"
echo "mount /etc as ramfs"
/bin/mount -n -t ramfs ramfs /etc
/bin/cp -a /mnt/etc/* /etc
echo "re-create the /etc/mtab entries"
/bin/mount -f -t cramfs -o remount,ro /dev/bon/3 /
/bin/mount -f -t ramfs ramfs /etc
echo "start init"
exec /sbin/init
lingd@ubuntu:~/arm2410s/rootfs$ ls
bin dev etc home lib linuxrc mnt proc root sbin sys tmp usr var
Linuxrc 腳本分析
/bin/mount -n -t ramfs ramfs /etc
這句話的作用加載一個ramfs作為/etc目錄。這樣 /etc就是一個可寫目錄。
從這個腳本可知,你的根文件系統(tǒng)是一個cramfs(只讀文件系統(tǒng)),而/etc作為系統(tǒng)運行配置文件的存放地點,可 能會寫一些運行狀態(tài)在這里,linuxrc第一件事情就是將一個ramfs mount到/etc只讀目錄中,使得/etc/目錄可寫,指定參數(shù) -n的目的是告訴mount不要寫/etc/mtab, 這個文件存放當(dāng)前系統(tǒng)已掛載(mount)的文件系統(tǒng)清單。因為現(xiàn)在/etc/目錄還是只讀,所以這次mount不要寫這個文件,否則會失敗。而且 mount上后,原/etc會覆蓋掉(原/etc下的文件都不見了,umount后會重新出現(xiàn)),所以我們把配置文件都保存在/mnt /etc,mount上ramfs到/etc后,再把配置文件拷貝到/etc。而不是直接將配置文件保存在/etc/下
/bin/cp -a /mnt/etc/* /etc
/etc成為可寫目錄后,將所有/mnt/etc中的配置文件拷貝到/etc/中,這說明ramfs可能 是一個空的ramfs,沒有配置文件,或者配置文件比較老。同時也說明這個系統(tǒng)是一個只讀系統(tǒng),每次系統(tǒng)運行中寫入的配置不會保留。
將以前 mount的那些信息重新寫到/etc/mtab中,命令就是下面這些。
/bin/mount -f -t cramfs -o remount,ro /dev/bon/3 /
/bin/mount -f -t ramfs ramfs /etc
這些命令只是將這 些mount信息寫到/etc/mtab中,不會實際去mount這些block device,說明你的根文件系統(tǒng)依然是以前的那個/dev/bon/3
exec /sbin/init
執(zhí)行根文件系統(tǒng)中的init執(zhí)行 程序,使其成為1號進(jìn)程。shell正式運行。
3.3、rcS
rcS 文件位于/etc/init.d,是busybox版init第一個運行的腳步(常見的init還有Sys V init版,其第一個執(zhí)行的腳步是/etc/rc.d/rc.sysinit)。/mnt/etc/init.d/rcS 完成各個文件系統(tǒng)的 mount,再執(zhí)行/mnt/etc/rc.local;通過rcS 可以調(diào)用 ifconfig 程序配置網(wǎng)絡(luò)。rcS 執(zhí)行完了以后,init 就會在一個 console 上,按照 inittab 的指示開一個 shell,或者是開 getty + login,這樣用戶就會看到提示輸入用戶名的提示符。/etc/init.d/rcS文件內(nèi)容如下:
lingd@ubuntu:~/arm2410s/rootfs$ cd mnt/etc/init.d
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc/init.d$ vi rcS
/etc/init.d/rcS內(nèi)容如下:
#!/bin/sh
echo "Processing /etc/init.d/rcS"
echo "mount -a"
mount -a #mount上fstab文件中所有文件系統(tǒng)
exec /etc/rc.local
3.4、/etc/rc.local
/etc/rc.local是被init.d/rcS 文件調(diào)用執(zhí)行的特殊文件,與Linux 系統(tǒng)硬件平臺相關(guān),如安裝核心模塊、進(jìn)行網(wǎng)絡(luò)配置、運行應(yīng)用程序、啟動圖形界面等。內(nèi)容如下:
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc/init.d$ cd ..
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi rc.local
/etc/rc.local內(nèi)容如下:
#!/bin/sh
echo "Processing /etc/rc.local"
echo "get hostname"
/bin/hostname -F /etc/hostname
echo "Starting mdev"
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
echo "ifconfig eth0 192.168.1.21"
ifconfig eth0 192.168.1.21
echo "**************************************************"
echo "* *"
echo "* lingd rootfs for linux 2.6.24.7 *"
echo "* *"
echo "* arm-linux-gcc version 4.1.1 *"
echo "* *"
echo "* 2010-03-30 *"
echo "* *"
echo "**************************************************"
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ ls
init.d rc.local
在rc.local使用了"/bin/hostname -F /etc/hostname"來設(shè)置主機名(設(shè)置主機名主要是為了后面設(shè)置命令提示符PS1)。這條命令需要了一個主機名配置文件/etc /hostname,其內(nèi)容如下:
arm2410s
3.5、/etc/profile
rc.local 首先執(zhí)行該文件配置應(yīng)用程序需要的環(huán)境變量等。
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi profile
/etc/profile內(nèi)容如下:
#/etc/profile
echo "Processing /etc/profile"
echo "set user path"
PATH=/bin:/sbin:/usr/bin:/usr/sbin
echo "set search library path"
LD_LIBRARY_PATH=/lib:/usr/lib
echo "set PS1"
HOSTNAME=`/bin/hostname`
PS1='\u@\h:\w\$ ' #設(shè)置命令提示符為ubuntu風(fēng)格
export PATH LD_LIBRARY_PATH HOSTNAME PS1
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ ls
init.d profile rc.local
改變這四個文件的權(quán)限
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ cd ../..
lingd@ubuntu:~/arm2410s/rootfs$ chmod 775 linuxrc mnt/etc/init.d/rcS mnt/etc/rc.local mnt/etc/profile
3.6、/etc/inittab
內(nèi)核引導(dǎo)完成后,內(nèi)核會啟動初始化進(jìn)程init(用戶級進(jìn)程)來進(jìn)行 系統(tǒng)的各項配置。init是系統(tǒng)第一個進(jìn)程,它是系統(tǒng)上運行的所有其他進(jìn)程的父進(jìn)程,他會觀察其子進(jìn)程,并在需要時啟動、停止、重啟它們。init主要是 用來完成系統(tǒng)的各項配置。init從/etc/inittab獲取所有信息。想了解BusyBox init及其inittab基本原理的,可以看這篇文章
http://blog.chinaunix.net/u3/109117/showart_2208026.html。lingd@ubuntu:~/arm2410s/rootfs$ cd mnt/etc
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi inittab
/etc /inittab內(nèi)容如下:
#/etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
"console::askfirst:-/bin/sh"中 的-表示的是讓busybox開啟一個登錄(login)shell,login shell在執(zhí)行前都會讀取配置文件/etc/profile和.profile。由BusyBox源碼的shell/ash.c文件可知 這一點:
int ash_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
…………
if (argv[0] && argv[0][0] == '-')
isloginsh = 1;
if (isloginsh) {
state = 1;
read_profile("/etc/profile");
state1:
state = 2;
read_profile(".profile");
…………
}
因為我們在/etc/profile對PATH、LD_LIBRARY_PATH、 HOSTNAME、PS1等環(huán)境變量進(jìn)行了修改,所以BusyBox開啟的必須是一個login shell(這樣可以保證/profile的內(nèi)容對開發(fā)板上所有shell都是有效的);否則/etc/profile定義的內(nèi)容將不會執(zhí)行。
做 個小實驗(以這次做好的根文件系統(tǒng)為基礎(chǔ)):
Please press Enter to activate this console. #啟動開發(fā)板,引導(dǎo)linux內(nèi)核并進(jìn)行各系統(tǒng)配置后,執(zhí)行到這里。按下回車鍵,顯示以下內(nèi) 容:
starting pid 797, tty '/dev/console': '-/bin/sh ' #在控制臺/dev/console上開啟一個login shell
Processing /etc/profile #執(zhí)行/etc/profile配置文 件
set user path
set search library path
set PS1
root@arm2410s:/#
root@arm2410s:/# exit #退出當(dāng)前 shell
Please press Enter to activate this console. #再按回車開啟一個新的login shell
starting pid 799, tty '/dev/console': '-/bin/sh '
Processing /etc/profile #再次執(zhí)行/etc/profile配置文 件
set user path
set search library path
set PS1
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ ls
init.d inittab profile rc.local
3.7、/etc/fstab
文件/etc/fstab存放的是系統(tǒng)中的文件系統(tǒng)信息。當(dāng)正確的設(shè)置了該 文件,則可以通過"mount /directoryname"命令來加載一個文件系統(tǒng),或mount -a來加載該文件中所有文件系統(tǒng)。每種文件系統(tǒng)都對應(yīng)一個獨立的行,每行中的字段都有空格或tab鍵分開。同時fsck、mount、umount的等命 令都利用該程序。
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi fstab
fstab文件內(nèi)容如下:
#/etc/fstab: static file system information.
#<File system> <mount pt> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
mdev /dev ramfs defaults 0 0
none /tmp ramfs defaults 0 0
注意: 已單獨mount了的文件系統(tǒng),就不要出現(xiàn)在/etc/fstab文件中,以免使用mount -a時把先前已經(jīng)mount上的文件系統(tǒng)被覆蓋了。
3.8、/etc/passwd
/etc/passwd文件存放著所有用戶的信息,包括賬號和密碼。內(nèi)容如下:
#username:password:User ID:Group ID:comment:home directory:shell
root:x:0:0:root:/root:/bin/sh
4、編譯busybox
BusyBox下載地址:
http://www.busybox.net/lingd@ubuntu:~/arm2410s$ tar xjvf busy-1.11.1.tar.bz2
lingd@ubuntu:~/arm2410s$ cd busybox-1.11.1
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ vi Makefile
首先修改 Makefile ,將以下兩項改為
CROSS_COMPILE = arm-linux-
ARCH = arm
配置busybox,修改以下選項(其他選項默認(rèn)就可 以了,或者根據(jù)需要再裁減一下):
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ make menuconfig
Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary (no shared libs)
[ ] Build with Large File Support (for accessing files > 2 GB)
Installation Options --->
[*] Don't use /usr #這項必選選上,否則BusyBox默認(rèn)安裝路徑是/usr,原/usr下的東西可能會被覆蓋了
Applets links (as soft-links) --->
(./_install) BusyBox installation prefix
Busybox Library Tuning --->
[*] Command line editing
(1024) Maximum length of input
[*] vi-style line editing commands
(15) History size
[*] History saving
[*] Tab completion
[*] Username completion
[*] Fancy shell prompts
這兩項必須選上,不然BusyBox將無法識別環(huán)境變量PS1里的參數(shù)。
Linux Module Utilities --->
[*] insmod
[*] Enable load map (-m) option
[*] Symbols in load map
[*] rmmod
[*] lsmod
[*] Pretty output for 2.6.x Linux kernels
[*] modprobe
[ ] Multiple options parsing
[ ] Fancy alias parsing
[ ] Blacklist support
--- Options common to multiple modutils
[ ] Support tainted module checking with new kernels
[ ] Support version 2.2.x to 2.4.x Linux kernels
[*] Support version 2.6.x Linux kernels
(/lib/modules) Default directory containing modules
(modules.dep) Default name of modules.dep
保存退出 Busybox
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ make
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ make install
編譯BusyBox時,可能會出現(xiàn)以下錯誤:
4.1、inotifyd出錯
交叉編譯busybox-1.11.1時,出現(xiàn)以下錯誤:
CC miscutils/inotifyd.o
miscutils/inotifyd.c:31:27: linux/inotify.h: No such file or directory
miscutils/inotifyd.c: In function `inotifyd_main':
miscutils/inotifyd.c:61: error: `IN_ALL_EVENTS' undeclared (first use in this function)
miscutils/inotifyd.c:61: error: (Each undeclared identifier is reported only once
miscutils/inotifyd.c:61: error: for each function it appears in.)
miscutils/inotifyd.c:129: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:139: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:140: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:140: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:143: error: invalid application of `sizeof' to incomplete type `inotify_event'
miscutils/inotifyd.c:143: error: dereferencing pointer to incomplete type
make[1]: *** [miscutils/inotifyd.o] Error 1
make: *** [miscutils] Error 2
網(wǎng)上說這是busybox的一個bug,解決方法:去掉對inotifyed的支持,具體步驟如下:
# make menuconfig
Miscellaneous Utilities --->
[ ]inotifyd
還有另一個bug是 taskset,也要將它去掉,不然編譯時又會出錯。
Miscellaneous Utilities --->
[ ]taskset
4.2、啟動時,BusyBox提示"/bin/sh:can't access tty;job console turn off"
解決方法:
shell --->
[ ]Job Console
[*]Cttyhack
4.3、未定義 ARPHRD_INFINIBAND
錯誤信息如下:
networking/interface.c:818: error: 'ARPHRD_INFINIBAND' undeclared here (not in a function)
make[1]: *** [networking/interface.o] Error 1
make: *** [networking] Error 2
通過查看內(nèi)核源代碼目錄中的“include/linux/ifarp.h”文件可知 “ARPHRD_INFINIBAND”的值為“32”。然后修改“networking/interface.c”文件,在其中添加:
#define ARPHRD_INFINIBAND 32 /* InfiniBand */
默認(rèn)在_install目錄中生成基本的文件系統(tǒng), 包括以下目錄或文件bin、sbin、linuxrc該目錄下包含了基本的 shell 命令.將編譯好的BusyBox的_Install目錄下的bin和sbin用tar命令打包復(fù)制到~/rootfs目錄,解壓后刪除打包文件。
lingd@ubuntu:~/arm2410s/busybox-1.11.1$ cd _install
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ ls
bin linuxrc sbin
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ tar zcvf rootfs.tar.gz bin sbin
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ ls
bin linuxrc rootfs.tar.gz sbin
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ mv rootfs.tar.gz ../../rootfs
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ ls
bin linuxrc sbin
lingd@ubuntu:~/arm2410s/busybox-1.11.1/_install$ cd ../../rootfs
lingd@ubuntu:~/arm2410s/rootfs$ ls
bin etc lib mnt root sbin tmp var
dev home linuxrc proc rootfs.tar.gz sys usr
lingd@ubuntu:~/arm2410s/rootfs$ tar zvxf rootfs.tar.gz
lingd@ubuntu:~/arm2410s/rootfs$ rm rootfs.tar.gz
5、 lib庫文件復(fù)制到rootfs/lib目錄下(根據(jù)需要復(fù)制)
lingd@ubuntu:~/arm2410s/rootfs$ cd /opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR ld* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libc*.so* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libcrypt* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libgcc_s.so* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libm* ~/arm2410s/rootfs/lib
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cp -dR libpthread.so* ~/arm2410s/rootfs/lib
6、生成 CramFS文件系統(tǒng)鏡像文件CramFS.img
首先從http://sourceforge.net/projects/cramfs/下載 cramfs-1.1.tar.gz
lingd@ubuntu:/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/arm-linux/lib$ cd ~/arm2410s
lingd@ubuntu:~/arm2410s$ tar zxvf cramfs-1.1.tar.gz
lingd@ubuntu:~/arm2410s$ cd cramfs-1.1
lingd@ubuntu:~/arm2410s/cramfs-1.1$ ls
COPYING cramfsck.c GNUmakefile linux mkcramfs.c NOTES README
lingd@ubuntu:~/arm2410s/cramfs-1.1$ make
gcc -W -Wall -O2 -g -I. mkcramfs.c -lz -o mkcramfs
gcc -W -Wall -O2 -g -I. cramfsck.c -lz -o cramfsck
在 cramfs-1.1目錄下會出現(xiàn)兩個bin文件mkcramfs和cramfsck
lingd@ubuntu:~/arm2410s/cramfs-1.1$ ls
COPYING cramfsck.c linux mkcramfs.c README
cramfsck GNUmakefile mkcramfs NOTES
把他們copy到/usr/bin:
lingd@ubuntu:~/arm2410s/cramfs-1.1$ sudo cp mkcramfs cramfsck /usr/bin
創(chuàng)建根文件系統(tǒng)的cramfs鏡像
lingd@ubuntu:~/arm2410s/cramfs-1.1$ mkcramfs ../rootfs CramFS01.img
Directory data: 6020 bytes
Everything: 908 kilobytes
Super block: 76 bytes
CRC: 526c6bb5
warning: gids truncated to 8 bits (this may be a security concern)
lingd@ubuntu:~/arm2410s/cramfs-1.1$ ls
COPYING cramfsck GNUmakefile mkcramfs NOTES
CramFS01.img cramfsck.c linux mkcramfs.c README
測試一下剛生成的CramFS01.img:
lingd@ubuntu:~/arm2410s/cramfs-1.1$ sudo mount -o loop -t cramfs ~/CramFS01.img /mnt/usb
lingd@ubuntu:~/arm2410s/cramfs-1.1$ ls /mnt/usb
查 看是否有bin、etc等目錄
編譯cramfs時出現(xiàn)如下錯誤:
mkcramfs.c:37:18: zlib.h: No such file or directory
mkcramfs.c: In function `write_superblock':
mkcramfs.c:392: warning: implicit declaration of function `crc32'
mkcramfs.c:392: error: `Z_NULL' undeclared (first use in this function)
mkcramfs.c:392: error: (Each undeclared identifier is reported only once
mkcramfs.c:392: error: for each function it appears in.)
mkcramfs.c: In function `do_compress':
mkcramfs.c:598: warning: implicit declaration of function `compress2'
mkcramfs.c:598: error: `Z_BEST_COMPRESSION' undeclared (first use in this function)
mkcramfs.c:599: error: `Z_OK' undeclared (first use in this function)
mkcramfs.c:600: warning: implicit declaration of function `zError'
mkcramfs.c: In function `main':
mkcramfs.c:824: error: `Z_NULL' undeclared (first use in this function)
make: *** [mkcramfs] Error 1
原因沒安裝 zlib-devel包
在ubuntu軟件源里zlib和zlib-devel叫做zlib1g zlib1g.dev
$ sudo apt-get install zlib1g
$ sudo apt-get install zlib1g.dev
參考文章
ARM嵌入式Linux系統(tǒng)開發(fā)技術(shù)詳解 楊水清、張劍、施云飛等編著
使 用mdev制作cramfs根文件系統(tǒng)
http://hi.baidu.com/kkernel/blog/item/cf2d6845b917e836879473b3.html
飛 凌OK-2440-III文件系統(tǒng)移植-------busybox+mdev
http://bbs.21ic.com/icview-155436-1-1.html
s3c2410 平臺linux2.6.22內(nèi)核的文件系統(tǒng)移植總結(jié)
http://hi.baidu.com/hzau_wall_e/blog/item/76258afb58b6b5819e5146cc.html/cmtid/d4e418ee679a101cfdfa3cd4
linuxrc 詳解
http://blog.chinaunix.net/u1/38576/showart_444508.html
詳解 Linuxrc、rcS、rc.local、Profile
http://hi.baidu.com/wangy0919/blog/item/1e0bc18fd27f86f8513d92fb.html
使 用Busybox制作CRAMFS文件系統(tǒng)成功
http://linux.chinaunix.net/techdoc/system/2008/08/20/1026770.shtml關(guān)于根文件系統(tǒng)中命令行提示符的顯示
http://www.eefocus.com/ayayayaya/blog/10-01/183654_4d808.html 制作嵌入式根文件系統(tǒng)(常見問題詳解) 首先介紹點背景知識,關(guān)于inittab的:init進(jìn)程是
系統(tǒng)中所有進(jìn)程的父進(jìn)程,init進(jìn)程繁衍出完成通常操作所需的子進(jìn)程,這些操作包括:設(shè)置機器名、檢查和安裝磁盤及文件系統(tǒng)、
啟動系統(tǒng)日志、配置網(wǎng)絡(luò)接口并啟動網(wǎng)絡(luò)和郵件服務(wù),啟動打印服務(wù)等。Solaris中init進(jìn)程的主要任務(wù)是按照inittab文件所提供的信息創(chuàng)建進(jìn)程,由于進(jìn)行系統(tǒng)初始化的那些進(jìn)程都由init創(chuàng)建,所以init進(jìn)程也稱為系統(tǒng)初始化進(jìn)程。
下面具體說明inittab文件的格式。
inittab文件中每一記錄都從新的一行開始,每個記錄項最多可有512個字符,每一項的格式通常如下:id:rstate:action:process,下面分別解釋。
1.id字段是最多4個字符的字符串,用來唯一標(biāo)志表項。
2.rstate(run state)字段定義該記錄項被調(diào)用時的運行級別,rstate可以由一個或多個運行級別構(gòu)成,也可以是空,空則代表運行級別0~6。當(dāng)請求init改變運行級別時,那些rstate字段中不包括新運行級別的進(jìn)程將收到SIGTERM警告信號,并且最后被殺死;只有a、b、c啟動的命令外(a、b、c不是真正的運行級別)
3.action字段告訴init執(zhí)行的動作,即如何處理process字段指定的進(jìn)程,action字段允許的值及對應(yīng)的動作分別為:
1)respawn:如果process字段指定的進(jìn)程不存在,則啟動該進(jìn)程,init不等待處理結(jié)束,而是繼續(xù)掃描inittab文件中的后續(xù)進(jìn)程,當(dāng)這樣的進(jìn)程終止時,init會重新啟動它,如果這樣的進(jìn)程已存在,則什么也不做。
2)wait:啟動process字段指定的進(jìn)程,并等到處理結(jié)束才去處理inittab中的下一記錄項。
3)once:啟動process字段指定的進(jìn)程,不等待處理結(jié)束就去處理下一記錄項。當(dāng)這樣的進(jìn)程終止時,也不再重新啟動它,在進(jìn)入新的運行級別時,如果這樣的進(jìn)程仍在運行,init也不重新啟動它。
4)boot:只有在系統(tǒng)啟動時,init才處理這樣的記錄項,啟動相應(yīng)進(jìn)程,并不等待處理結(jié)束就去處理下一個記錄項。當(dāng)這樣的進(jìn)程終止時,系統(tǒng)也不重啟它。
5)bootwait:系統(tǒng)啟動后,當(dāng)?shù)谝淮螐膯斡脩裟J竭M(jìn)入多用戶模式時處理這樣的記錄項,init啟動這樣的進(jìn)程,并且等待它的處理結(jié)束,然后再進(jìn)行下一個記錄項的處理,當(dāng)這樣的進(jìn)程終止時,系統(tǒng)也不重啟它。
6)powerfail:當(dāng)init接到斷電的信號(SIGPWR)時,處理指定的進(jìn)程。
7)powerwait:當(dāng)init接到斷電的信號(SIGPWR)時,處理指定的進(jìn)程,并且等到處理結(jié)束才去檢查其他的記錄項。
8)off:如果指定的進(jìn)程正在運行,init就給它發(fā)SIGTERM警告信號,在向它發(fā)出信號SIGKILL強制其結(jié)束之前等待5秒,如果這樣的進(jìn)程不存在,則忽略這一項。
9)ondemand:功能通respawn,不同的是,與具體的運行級別無關(guān),只用于rstate字段是a、b、c的那些記錄項。
10)sysinit:指定的進(jìn)程在訪問控制臺之前執(zhí)行,這樣的記錄項僅用于對某些設(shè)備的初始化,目的是為了使init在這樣的設(shè)備上向用戶提問有關(guān)運行級別的問題,init需要等待進(jìn)程運行結(jié)束后才繼續(xù)。
11)initdefault:指定一個默認(rèn)的運行級別,只有當(dāng)init一開始被調(diào)用時才掃描這一項,如果rstate字段指定了多個運行級別,其中最大的數(shù)字是默認(rèn)的運行級別,如果rstate字段是空的,init認(rèn)為字段是0123456,于是進(jìn)入級別6,這樣便陷入了一個循環(huán),如果 inittab文件中沒有包含initdefault的記錄項,則在系統(tǒng)啟動時請求用戶為它指定一個初始運行級別
4.Process字段中進(jìn)程可以是任意的守候進(jìn)程、可執(zhí)行腳本或程序。
另外:在
任何時候,可以在文件inittab中添加新的記錄項,級別Q/q不改變當(dāng)前的運行級別,重新檢查inittab文件,可以通過命令init Q或init q使init進(jìn)程立即重新讀取并處理文件inittab
以上這些都是介紹的標(biāo)準(zhǔn)的linux System V的標(biāo)準(zhǔn),所以對嵌入式來講有些東西并不見得有用!這里介紹點針對嵌入式的,也就是針對busybox init的:
的init
除了基本的命令之外,BusyBox還支持init功能,如同其它的init一樣,busybox的init也是完成系統(tǒng)的初始化工作,關(guān)機前的工作等等,我們知道在Linux的內(nèi)核被載入之后,機器就把控制權(quán)轉(zhuǎn)交給內(nèi)核,linux的內(nèi)核啟動之后,做了一些工作,然后找到根文件系統(tǒng)里面的init程序,并執(zhí)行它,BusyBox的init進(jìn)程會依次進(jìn)行以下工作:(參考<<構(gòu)建嵌入式LINUX系統(tǒng)>> p201)
1. 為init設(shè)置信號處理過程
2. 初始化控制臺
3. 剖析/etc/inittab文件
4. 執(zhí)行系統(tǒng)初始化命令行,缺省情況下會使用/etc/init.d/rcS
5. 執(zhí)行所有導(dǎo)致init暫停的inittab命令(動作類型:wait)
6. 執(zhí)行所有僅執(zhí)行一次的inittab(動作類型:once)
一旦完成以上工作,init進(jìn)程便會循環(huán)執(zhí)行以下進(jìn)程:
1. 執(zhí)行所有終止時必須重新啟動的inittab命令(動作類型:once)
2. 執(zhí)行所有終止時必須重新啟動但啟動前必須詢問用戶的inittab命令(動作類型:askfirst)
初始化控制臺之后,BusyBox會檢查/etc/inittab文件是否存在,如果此文件不存在,BusyBox會使用缺省的inittab配置,它主要為系統(tǒng)重引導(dǎo),系統(tǒng)掛起以及init重啟動設(shè)置缺省的動作,此外它還會為四個虛擬控制臺(tty1到tty4)設(shè)置啟動shell的動作。如果未建立這些設(shè)備文件,BusyBox會報錯。
inittab文件中每一行的格式如下所示:(busybox的根目錄下的example文件夾下有詳盡的inittab文件范例)
id:runlevel:action:process
盡管此格式與傳統(tǒng)的Sytem V init類似,但是,id在BusyBox的init中具有不同的意義。對BusyBox而言,id用來指定啟動進(jìn)程的控制tty。如果所啟動的進(jìn)程并不是可以交互的shell,例如BusyBox的sh(ash),應(yīng)該會有個控制tty,如果控制tty不存在,Busybox的sh會報錯。BusyBox將會完全忽略runlevel字段,所以空著它就行了,你也許會問既然沒用保留著它干嗎,我想大概是為了和傳統(tǒng)的Sytem V init保持一致的格式吧。process字段用來指定所執(zhí)行程式的路徑,包括命令行選項。action字段用來指定下面表中8個可應(yīng)用到process的動作之一。
動作
結(jié)果
sysinit
為init提供初始化命令行的路徑
respawn
每當(dāng)相應(yīng)的進(jìn)程終止執(zhí)行便會重新啟動
askfirst
類似respawn,不過它的主要用途是減少系統(tǒng)上執(zhí)行的終端應(yīng)用程序的數(shù)量。它將會促使init在控制臺上顯示“Please press Enter to active this console”的信息,并在重新啟動之前等待用戶按下enter鍵
wait
告訴init必須等到相應(yīng)的進(jìn)程完成之后才能繼續(xù)執(zhí)行
once
僅執(zhí)行相應(yīng)的進(jìn)程一次,而且不會等待它完成
ctratldel
當(dāng)按下Ctrl+Alt+Delete組合鍵時,執(zhí)行相應(yīng)的進(jìn)程
shutdown
當(dāng)系統(tǒng)關(guān)機時,執(zhí)行相應(yīng)的進(jìn)程
restart
當(dāng)init重新啟動時,執(zhí)行相應(yīng)的進(jìn)程,通常此處所執(zhí)行的進(jìn)程就是init本身
以下是我的usblinux的inittab文件
::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty 115200 tty1
tty2::askfirst:-/bin/sh
tty3::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/bin/umount -a -r
這個inittab執(zhí)行下列動作
1. 將/etc/init.d/rcS設(shè)置成系統(tǒng)的初始化文件
2. 在115200 bps的虛擬終端tty1上啟動一個登陸會話 (注意getty的用法)
3. 在虛擬終端tty2和tty3上啟動askfirst動作的shell
4. 如果init重新啟動,將/sbin/init設(shè)置成它會執(zhí)行的程序
5. 告訴init,在系統(tǒng)關(guān)機的時候執(zhí)行umount命令卸載所有文件系統(tǒng),并且在卸載失敗時用只讀模式?jīng)_新安裝以保護文件系統(tǒng)。
1、busybox的inittab與pc使用的inittab不同,第一ID并不是隨便取名字的,這個名字要與/dev/目錄下是否有對應(yīng)的文件對應(yīng)
對應(yīng)錯誤
can't open /dev/0: No such file or directory
process '-/bin/sh' (pid 789) exited. Scheduling for restart.
can't open /dev/0: No such file or directory
process '-/bin/sh' (pid 793) exited. Scheduling for restart.
2、出現(xiàn)下面這種錯誤:
process '-/bin/sh' (pid 789) exited. Scheduling for restart.
process '-/bin/sh' (pid 794) exited. Scheduling for restart.
process '-/bin/sh' (pid 796) exited. Scheduling for restart.
process '-/bin/sh' (pid 798) exited. Scheduling for restart.
對應(yīng)的inittab文件中有
ttyS0::askfirst:-/bin/sh
雖然在/dev/目錄下有ttyS0設(shè)備,但是這個設(shè)備顯然不可用,所以才會出現(xiàn)上面的錯誤
3、當(dāng)在inittab中同時定義的兩個在同一個串口終端登陸的語句時
::askfirst:-/bin/sh
s3c2410_serial0:23456:respawn:/sbin/getty -L s3c2410_serial0 115200 vt100
出現(xiàn)的情況就是被搶占,不能接收任何串口輸入
4、bad inittab entry
多半時因為非法字符造成的。
5、busybox中的字段runleve也沒有運行時的運行級別的概念
6、分析一下啟動的過程
1. 為init設(shè)置信號處理過程
2. 初始化控制臺
3. 剖析/etc/inittab文件
4. 執(zhí)行系統(tǒng)初始化命令行,缺省情況下會使用/etc/init.d/rcS
5. 執(zhí)行所有導(dǎo)致init暫停的inittab命令(動作類型:wait)
6. 執(zhí)行所有僅執(zhí)行一次的inittab(動作類型:once)
一旦完成以上工作,init進(jìn)程便會循環(huán)執(zhí)行以下進(jìn)程:
1. 執(zhí)行所有終止時必須重新啟動的inittab命令(動作類型:once)
2. 執(zhí)行所有終止時必須重新啟動但啟動前必須詢問用戶的inittab命令(動作類型:askfirst)
初始化控制臺之后,BusyBox會檢查/etc/inittab文件是否存在,如果此文件不存在,BusyBox會使用缺省的inittab配置,它主要為系統(tǒng)重引導(dǎo),系統(tǒng)掛起以及init重啟動設(shè)置缺省的動作,此外它還會為四個虛擬控制臺(tty1到tty4)設(shè)置啟動shell的動作。如果未建立這些設(shè)備文件,BusyBox會報錯。
7、網(wǎng)上有人問“-”的作用
我很納悶:
:: respawn:-/bin/sh
這個-是干什么的,為什么有的時候有有的時候沒有???
還有啊,我從網(wǎng)上看到一個例程,如下,節(jié)選:
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
我搞不清兩個的區(qū)別,這樣控制臺就啟動了,是第一句啟動的還是第二句,那我內(nèi)核啟動參數(shù)里面的console=ttyS0會自動來找這個控制臺???
原帖由 wavezone 于 2008-8-22 16:34 發(fā)表
我很納悶:
:: respawn:-/bin/sh
這個-是干什么的,為什么有的時候有有的時候沒有???
還有啊,我從網(wǎng)上看到一個例程,如下,節(jié)選:
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
我搞不清兩個的區(qū)別 ...
測試的時候是這樣的,加上”-”的語句會在登陸終端之后調(diào)用/etc/目錄下的profile文件,而不加”-”的不會執(zhí)行這個腳本。
其實登陸終端的命令有幾種方便,但是標(biāo)準(zhǔn)的還是使用getty來登陸,但是直接使用如上的語句也是可以的,并且兼容性強一點,因為它不需要指定對應(yīng)的串口設(shè)備。
::askfirst:-/bin/sh
s3c2410_serial0::askfirst:-/bin/sh
::askfirst:-/bin/sh
s3c2410_serial0:23456:respawn:/sbin/getty -L s3c2410_serial0 115200 vt100
都是可用的。
8./bin/sh: XXX not found
arm-linux-readelf -d xxx
查看你的以用程序依賴哪些庫
一般是因為缺少libc.so.6造成的,實際還是根文件系統(tǒng)的問題,沒有將常用的庫文件拷貝到/lib目錄下
常用的庫:
[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/ld* .
[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/libc-2.3.2.so .
[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/libc.so.6 .
[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/libm * .
[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/libcrypt* .
9、錯誤insmod: chdir(2.6.26.6): No such file or directory
網(wǎng)上有人提出這種解決方法:
需要注意的是insmod等模塊加載命令需要從lib/modules/2.6.26.6
的目錄下加載模塊,所以必須先建立此目錄,然后將模塊放到此目錄下面,否則將出現(xiàn)以下兩種情況:
一是沒有建立lib/modules/2.6.26.6目錄,取決于內(nèi)核版本號,將出現(xiàn)insmod: chdir(2.6.26.6): No such file or directory的錯誤
二是只將模塊簡單地放在根目錄或其它文件夾,沒有將其拷貝到指定的lib/modules/2.6.26.6目錄,將出現(xiàn)
insmod: module 'gpio_driver' not found錯誤
不過這種方法不是很奏效
根本原因是insmod的問題,在busybox編譯的時候參考下面的選項,不要使用
Linux Module Utilities --->
[ ] Simplified modutils
//該選項不要選擇
[*] Support version 2.6.x Linux kernels
//此選項選上
參考如下:
10、不能執(zhí)行”-h”命令
在執(zhí)行xxx –h時沒有任何反應(yīng)。是在lib目錄下缺少常見的庫文件
參考如下:
[root@vm-dev rootfs]# ls lib/
ld-2.3.6.so libc-2.3.6.so libgcc_s.so libnsl.so.1 libnss_files.so.2 libnss_nis.so.2 librt-2.3.6.so libthread_db.so.1
ld-linux.so.2 libcrypt-2.3.6.so libgcc_s.so.1 libnss_compat-2.3.6.so libnss_hesiod-2.3.6.so libpcprofile.so librt.so.1 libutil-2.3.6.so
libanl-2.3.6.so libcrypt.so.1 libm-2.3.6.so libnss_compat.so.2 libnss_hesiod.so.2 libpthread-0.10.so libSegFault.so libutil.so.1
libanl.so.1 libc.so.6 libmemusage.so libnss_dns-2.3.6.so libnss_nis-2.3.6.so libpthread.so.0 libtermcap.so.2 modules
libBrokenLocale-2.3.6.so libdl-2.3.6.so libm.so.6 libnss_dns.so.2 libnss_nisplus-2.3.6.so libresolv-2.3.6.so libtermcap.so.2.0.8
libBrokenLocale.so.1 libdl.so.2 libnsl-2.3.6.so libnss_files-2.3.6.so libnss_nisplus.so.2 libresolv.so.2 libthread_db-1.0.so
[root@vm-dev rootfs]#