转:http://www.360doc.com/content/10/0428/11/496343_25245348.shtml

操作系统:Ubuntu9.04
内核版本:linux-2.6.24.7  
开发板:博创arm2410s    
交叉编译工具:arm-linux-gcc-4.1.1 
BusyBox:busybox-1.11.1      
CramFS:CramFS-1.1
 
注意:由于要制作的根文件系统使用了mdev(BusyBox简化版的udev),因此,需要内 核支持sysfs、procfs和ramfs(tmpfs)文件系统以及hotplug(uevent)事件机制。
 
浅蓝色为命令,橘红色为 代码和脚步
1、准备根文件系统
使用shell脚本create_rootfs.sh,建立根文件系统的目录框架
lingd@ubuntu:~/arm2410s$ vi create_rootfs.sh

create_rootfs.sh
内容如下:
#!/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添加执行权限
lingd@ubuntu:~/arm2410s$
chmod a+x create_rootfs.sh
执行create_rootfs.sh,建立根文件系统的目录框架
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、创建设备
文件
mdev 是通过 init 进程来启动的,在使用 mdev 构造 /dev 目录之前,init 至少要用到设备文件/dev/console、 /dev/null
,所以需要事先建立这两个设备文件:
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的主次设备号应为5和1.但是因为init在执行完/etc/init.d/rcS脚本后,就
会在一个控制台上,按照inittab的指示开一个shell(或者是开getty+login,这样用户就会看到提示输入用户名的提示符)。在mdev
-s未执行之前,/dev目录下只有我们创建的/dev/null和/dev/console,也就是说,没有控制台可供init用来按照inittab
的指示开一个shell。而在s3c24xx
系列芯片的串口驱动里面用了s3c2410_serial做为设备名(在内核源码的“drivers/serial/s3c2410.c”文件的949
行),因此,启动时可用s3c2410_serial0、s3c2410_serial1或s3c2410_serial2作为init用来按照
inittab的指示开一个shell的控制台,这里我用了串口0,即s3c2410_serial0(主次设备号为204和64)作为控制台。这里直接
将console当s3c2410_serial0,所以console的主次设备号才会为204和64。

3、准备一些配置文件和系统启动时所需的文件
3.1、mdev配置文件mdev.conf
mdev
会在/etc目录下找mdev的配置文件: mdev.conf.
如果该文件不存在,那么在执行mdev
–s这个命令时,会提示找不到mdev.conf。我们不需要mdev规则,所以只是touch生成一个空文件就OK了。当然也可以根据mdev的规则来
编写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
位于根文件系统的顶层目录/,这里为rootfs。/Linuxrc 执行init 进程初始化文件。主要工作是把已安装根文件系统中的/etc
安装为ramfs,并拷贝/mnt/etc/目录下所有文件到/etc,这里存放系统启动后的许多特殊文件;接着Linuxrc
重新构建文件分配表inittab;之后执行系统初始化进程/sbin/init。
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$
cd ../..
lingd@ubuntu:~/arm2410s/rootfs$ vi linuxrc
linuxrc
内容如下:
#!/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就是一个可写目录。
从这个脚本可知,你的根文件系统是一个cramfs(只读文件系统),而/etc作为系统运行配置文件的存放地点,可
能会写一些运行状态在这里,linuxrc第一件事情就是将一个ramfs mount到/etc只读目录中,使得/etc/目录可写,指定参数
-n的目的是告诉mount不要写/etc/mtab,
这个文件存放当前系统已挂载(mount)的文件系统清单。因为现在/etc/目录还是只读,所以这次mount不要写这个文件,否则会失败。而且
mount上后,原/etc会覆盖掉(原/etc下的文件都不见了,umount后会重新出现),所以我们把配置文件都保存在/mnt
/etc,mount上ramfs到/etc后,再把配置文件拷贝到/etc。而不是直接将配置文件保存在/etc/下

/bin/cp
-a /mnt/etc/* /etc
/etc成为可写目录后,将所有/mnt/etc中的配置文件拷贝到/etc/中,这说明ramfs可能
是一个空的ramfs,没有配置文件,或者配置文件比较老。同时也说明这个系统是一个只读系统,每次系统运行中写入的配置不会保留。
将以前
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,说明你的根文件系统依然是以前的那个/dev/bon/3
exec /sbin/init
执行根文件系统中的init执行
程序,使其成为1号进程。shell正式运行。

3.3、rcS
rcS
文件位于/etc/init.d,是busybox版init第一个运行的脚步(常见的init还有Sys V
init版,其第一个执行的脚步是/etc/rc.d/rc.sysinit)。/mnt/etc/init.d/rcS 完成各个文件系统的
mount,再执行/mnt/etc/rc.local;通过rcS 可以调用 ifconfig 程序配置网络。rcS 执行完了以后,init
就会在一个 console 上,按照 inittab 的指示开一个 shell,或者是开 getty +
login,这样用户就会看到提示输入用户名的提示符。/etc/init.d/rcS文件内容如下:
lingd@ubuntu:~/arm2410s/rootfs$ cd mnt/etc/init.d
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc/init.d$
vi rcS
/etc/init.d/rcS内容如下:
#!/bin/sh
echo
"Processing /etc/init.d/rcS"

echo "mount -a"
mount -a
#mount上fstab文件中所有文件系统
exec /etc/rc.local

3.4、/etc/rc.local
/etc/rc.local是被init.d/rcS
文件调用执行的特殊文件,与Linux 系统硬件平台相关,如安装核心模块、进行网络配置、运行应用程序、启动图形界面等。内容如下:
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc/init.d$ cd ..
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$
vi rc.local
/etc/rc.local内容如下:
#!/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"来设置主机名(设置主机名主要是为了后面设置命令提示符PS1)。这条命令需要了一个主机名配置文件/etc
/hostname,其内容如下:
arm2410s
3.5、/etc/profile
rc.local
首先执行该文件配置应用程序需要的环境变量等。
lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi
profile
/etc/profile内容如下:
#/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\$ '
#设置命令提示符为ubuntu风格
export PATH LD_LIBRARY_PATH HOSTNAME PS1

lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ ls
init.d 
profile  rc.local

改变这四个文件的权限
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
内核引导完成后,内核会启动初始化进程init(用户级进程)来进行
系统的各项配置。init是系统第一个进程,它是系统上运行的所有其他进程的父进程,他会观察其子进程,并在需要时启动、停止、重启它们。init主要是
用来完成系统的各项配置。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内容如下:
#/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在执行前都会读取配置文件/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等环境变量进行了修改,所以BusyBox开启的必须是一个login
shell(这样可以保证/profile的内容对开发板上所有shell都是有效的);否则/etc/profile定义的内容将不会执行。

个小实验(以这次做好的根文件系统为基础):
Please press Enter to activate this
console.         #启动开发板,引导linux内核并进行各系统配置后,执行到这里。按下回车键,显示以下内
容:                            
starting pid 797, tty '/dev/console':
'-/bin/sh '    #在控制台/dev/console上开启一个login
shell                            
Processing
/etc/profile                              #执行/etc/profile配置文
件                            
set user
path                                                                    

set search library
path                                                          
set
PS1       
root@arm2410s:/#                                                        
root@arm2410s:/#
exit     #退出当前
shell                                                       
                                                                                 

Please press Enter to activate this
console.          #再按回车开启一个新的login shell                           
starting
pid 799, tty '/dev/console': '-/bin/sh
'                                
Processing
/etc/profile                               #再次执行/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存放的是系统中的文件系统信息。当正确的设置了该
文件,则可以通过"mount /directoryname"命令来加载一个文件系统,或mount
-a来加载该文件中所有文件系统。每种文件系统都对应一个独立的行,每行中的字段都有空格或tab键分开。同时fsck、mount、umount的等命
令都利用该程序。

lingd@ubuntu:~/arm2410s/rootfs/mnt/etc$ vi
fstab
fstab文件内容如下:
#/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了的文件系统,就不要出现在/etc/fstab文件中,以免使用mount -a时把先前已经mount上的文件系统被覆盖了。
 
3.8、/etc/passwd
/etc/passwd文件存放着所有用户的信息,包括账号和密码。内容如下:
#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,修改以下选项(其他选项默认就可
以了,或者根据需要再裁减一下):
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默认安装路径是/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将无法识别环境变量PS1里的参数。
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时,可能会出现以下错误:
4.1、inotifyd出错
交叉编译busybox-1.11.1时,出现以下错误:
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

网上说这是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

通过查看内核源代码目录中的“include/linux/ifarp.h”文件可知
“ARPHRD_INFINIBAND”的值为“32”。然后修改“networking/interface.c”文件,在其中添加:
#define
ARPHRD_INFINIBAND 32  /* InfiniBand */

默认在_install目录中生成基本的文件系统,
包括以下目录或文件bin、sbin、linuxrc该目录下包含了基本的 shell
命令.将编译好的BusyBox的_Install目录下的bin和sbin用tar命令打包复制到~/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库文件复制到rootfs/lib目录下(根据需要复制)
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文件系统镜像文件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目录下会出现两个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
创建根文件系统的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时出现如下错误:
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系统开发技术详解 杨水清、张剑、施云飞等编著
使
用mdev制作cramfs根文件系统
http://hi.baidu.com/kkernel/blog/item/cf2d6845b917e836879473b3.html

凌OK-2440-III文件系统移植-------busybox+mdev
http://bbs.21ic.com/icview-155436-1-1.html
s3c2410
平台linux2.6.22内核的文件系统移植总结
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文件系统成功
http://linux.chinaunix.net/techdoc/system/2008/08/20/1026770.shtml

关于根文件系统中命令行提示符的显示


制作嵌入式根文件系统(常见问题详解)

首先介绍点背景知识,关于inittab的:

init进程是系统中所有进程的父进程,init进程繁衍出完成通常操作所需的子进程,这些操作包括:设置机器名、检查和安装磁盘及文件系统、启动系统日志、配置网络接口并启动网络和邮件服务,启动打印服务等。Solaris中init进程的主要任务是按照inittab文件所提供的信息创建进程,由于进行系统初始化的那些进程都由init创建,所以init进程也称为系统初始化进程。
       下面具体说明inittab文件的格式。
  inittab文件中每一记录都从新的一行开始,每个记录项最多可有512个字符,每一项的格式通常如下:id:rstate:action:process,下面分别解释。
  1.id字段是最多4个字符的字符串,用来唯一标志表项。
  2.rstate(run state)字段定义该记录项被调用时的运行级别,rstate可以由一个或多个运行级别构成,也可以是空,空则代表运行级别0~6。当请求init改变运行级别时,那些rstate字段中不包括新运行级别的进程将收到SIGTERM警告信号,并且最后被杀死;只有a、b、c启动的命令外(a、b、c不是真正的运行级别)
  3.action字段告诉init执行的动作,即如何处理process字段指定的进程,action字段允许的值及对应的动作分别为:
         1)respawn:如果process字段指定的进程不存在,则启动该进程,init不等待处理结束,而是继续扫描inittab文件中的后续进程,当这样的进程终止时,init会重新启动它,如果这样的进程已存在,则什么也不做。
         2)wait:启动process字段指定的进程,并等到处理结束才去处理inittab中的下一记录项。
         3)once:启动process字段指定的进程,不等待处理结束就去处理下一记录项。当这样的进程终止时,也不再重新启动它,在进入新的运行级别时,如果这样的进程仍在运行,init也不重新启动它。
         4)boot:只有在系统启动时,init才处理这样的记录项,启动相应进程,并不等待处理结束就去处理下一个记录项。当这样的进程终止时,系统也不重启它。
         5)bootwait:系统启动后,当第一次从单用户模式进入多用户模式时处理这样的记录项,init启动这样的进程,并且等待它的处理结束,然后再进行下一个记录项的处理,当这样的进程终止时,系统也不重启它。
         6)powerfail:当init接到断电的信号(SIGPWR)时,处理指定的进程。
         7)powerwait:当init接到断电的信号(SIGPWR)时,处理指定的进程,并且等到处理结束才去检查其他的记录项。
         8)off:如果指定的进程正在运行,init就给它发SIGTERM警告信号,在向它发出信号SIGKILL强制其结束之前等待5秒,如果这样的进程不存在,则忽略这一项。
         9)ondemand:功能通respawn,不同的是,与具体的运行级别无关,只用于rstate字段是a、b、c的那些记录项。
            10)sysinit:指定的进程在访问控制台之前执行,这样的记录项仅用于对某些设备的初始化,目的是为了使init在这样的设备上向用户提问有关运行级别的问题,init需要等待进程运行结束后才继续。
         11)initdefault:指定一个默认的运行级别,只有当init一开始被调用时才扫描这一项,如果rstate字段指定了多个运行级别,其中最大的数字是默认的运行级别,如果rstate字段是空的,init认为字段是0123456,于是进入级别6,这样便陷入了一个循环,如果 inittab文件中没有包含initdefault的记录项,则在系统启动时请求用户为它指定一个初始运行级别
  4.Process字段中进程可以是任意的守候进程、可执行脚本或程序。
  另外:在任何时候,可以在文件inittab中添加新的记录项,级别Q/q不改变当前的运行级别,重新检查inittab文件,可以通过命令init Q或init q使init进程立即重新读取并处理文件inittab

以上这些都是介绍的标准的linux System V的标准,所以对嵌入式来讲有些东西并不见得有用!这里介绍点针对嵌入式的,也就是针对busybox init的:

busybox的init

除了基本的命令之外,BusyBox还支持init功能,如同其它的init一样,busybox的init也是完成系统的初始化工作,关机前的工作等等,我们知道在Linux的内核被载入之后,机器就把控制权转交给内核,linux的内核启动之后,做了一些工作,然后找到根文件系统里面的init程序,并执行它,BusyBox的init进程会依次进行以下工作:(参考<<构建嵌入式LINUX系统>> p201)

1.       为init设置信号处理过程

2.       初始化控制台

3.       剖析/etc/inittab文件

4.       执行系统初始化命令行,缺省情况下会使用/etc/init.d/rcS

5.       执行所有导致init暂停的inittab命令(动作类型:wait)

6.       执行所有仅执行一次的inittab(动作类型:once)

一旦完成以上工作,init进程便会循环执行以下进程:

1.  执行所有终止时必须重新启动的inittab命令(动作类型:once)

2.  执行所有终止时必须重新启动但启动前必须询问用户的inittab命令(动作类型:askfirst)

初始化控制台之后,BusyBox会检查/etc/inittab文件是否存在,如果此文件不存在,BusyBox会使用缺省的inittab配置,它主要为系统重引导,系统挂起以及init重启动设置缺省的动作,此外它还会为四个虚拟控制台(tty1到tty4)设置启动shell的动作。如果未建立这些设备文件,BusyBox会报错。

inittab文件中每一行的格式如下所示:(busybox的根目录下的example文件夹下有详尽的inittab文件范例)

id:runlevel:action:process

尽管此格式与传统的Sytem V init类似,但是,id在BusyBox的init中具有不同的意义。对BusyBox而言,id用来指定启动进程的控制tty。如果所启动的进程并不是可以交互的shell,例如BusyBox的sh(ash),应该会有个控制tty,如果控制tty不存在,Busybox的sh会报错。BusyBox将会完全忽略runlevel字段,所以空着它就行了,你也许会问既然没用保留着它干吗,我想大概是为了和传统的Sytem V init保持一致的格式吧。process字段用来指定所执行程式的路径,包括命令行选项。action字段用来指定下面表中8个可应用到process的动作之一。

动作

结果

sysinit

为init提供初始化命令行的路径

respawn

每当相应的进程终止执行便会重新启动

askfirst

类似respawn,不过它的主要用途是减少系统上执行的终端应用程序的数量。它将会促使init在控制台上显示“Please press Enter to active this console”的信息,并在重新启动之前等待用户按下enter键

wait

告诉init必须等到相应的进程完成之后才能继续执行

once

仅执行相应的进程一次,而且不会等待它完成

ctratldel

当按下Ctrl+Alt+Delete组合键时,执行相应的进程

shutdown

当系统关机时,执行相应的进程

restart

当init重新启动时,执行相应的进程,通常此处所执行的进程就是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执行下列动作

1.       将/etc/init.d/rcS设置成系统的初始化文件

2.       在115200 bps的虚拟终端tty1上启动一个登陆会话 (注意getty的用法)

3.       在虚拟终端tty2和tty3上启动askfirst动作的shell

4.       如果init重新启动,将/sbin/init设置成它会执行的程序

5.       告诉init,在系统关机的时候执行umount命令卸载所有文件系统,并且在卸载失败时用只读模式冲新安装以保护文件系统。

1、busybox的inittab与pc使用的inittab不同,第一ID并不是随便取名字的,这个名字要与/dev/目录下是否有对应的文件对应

对应错误

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、出现下面这种错误:

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.

对应的inittab文件中有

ttyS0::askfirst:-/bin/sh

虽然在/dev/目录下有ttyS0设备,但是这个设备显然不可用,所以才会出现上面的错误

3、当在inittab中同时定义的两个在同一个串口终端登陆的语句时

::askfirst:-/bin/sh

s3c2410_serial0:23456:respawn:/sbin/getty -L s3c2410_serial0 115200 vt100

出现的情况就是被抢占,不能接收任何串口输入

4、bad inittab entry

多半时因为非法字符造成的。

5、busybox中的字段runleve也没有运行时的运行级别的概念

6、分析一下启动的过程

1.       为init设置信号处理过程

2.       初始化控制台

3.       剖析/etc/inittab文件

4.       执行系统初始化命令行,缺省情况下会使用/etc/init.d/rcS

5.       执行所有导致init暂停的inittab命令(动作类型:wait)

6.       执行所有仅执行一次的inittab(动作类型:once)

一旦完成以上工作,init进程便会循环执行以下进程:

1.  执行所有终止时必须重新启动的inittab命令(动作类型:once)

2.  执行所有终止时必须重新启动但启动前必须询问用户的inittab命令(动作类型:askfirst)

初始化控制台之后,BusyBox会检查/etc/inittab文件是否存在,如果此文件不存在,BusyBox会使用缺省的inittab配置,它主要为系统重引导,系统挂起以及init重启动设置缺省的动作,此外它还会为四个虚拟控制台(tty1到tty4)设置启动shell的动作。如果未建立这些设备文件,BusyBox会报错。

7、网上有人问“-”的作用

我很纳闷:
:: respawn:-/bin/sh
这个-是干什么的,为什么有的时候有有的时候没有???
还有啊,我从网上看到一个例程,如下,节选:
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
我搞不清两个的区别,这样控制台就启动了,是第一句启动的还是第二句,那我内核启动参数里面的console=ttyS0会自动来找这个控制台???

原帖由 wavezone 于 2008-8-22 16:34 发表
我很纳闷:
:: respawn:-/bin/sh
这个-是干什么的,为什么有的时候有有的时候没有???
还有啊,我从网上看到一个例程,如下,节选:
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
我搞不清两个的区别 ...

测试的时候是这样的,加上”-”的语句会在登陆终端之后调用/etc/目录下的profile文件,而不加”-”的不会执行这个脚本。

其实登陆终端的命令有几种方便,但是标准的还是使用getty来登陆,但是直接使用如上的语句也是可以的,并且兼容性强一点,因为它不需要指定对应的串口设备。

::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造成的,实际还是根文件系统的问题,没有将常用的库文件拷贝到/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

网上有人提出这种解决方法:

需要注意的是insmod等模块加载命令需要从lib/modules/2.6.26.6

的目录下加载模块,所以必须先建立此目录,然后将模块放到此目录下面,否则将出现以下两种情况:

一是没有建立lib/modules/2.6.26.6目录,取决于内核版本号,将出现insmod: chdir(2.6.26.6): No such file or directory的错误

二是只将模块简单地放在根目录或其它文件夹,没有将其拷贝到指定的lib/modules/2.6.26.6目录,将出现

insmod: module 'gpio_driver' not found错误

不过这种方法不是很奏效

根本原因是insmod的问题,在busybox编译的时候参考下面的选项,不要使用

Linux Module Utilities --->

[ ] Simplified modutils

//该选项不要选择

[*] Support version 2.6.x Linux kernels

//此选项选上

参考如下:

10、不能执行”-h”命令

在执行xxx –h时没有任何反应。是在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]#

使用BusyBox制作linux根文件系统(CramFS+mdev)的更多相关文章

  1. 使用BusyBox制作Linux根文件系统

    STEP 1:构建目录结构 创建根文件系统目录,主要包括以下目录/dev  /etc /lib  /usr  /var /proc /tmp /home /root /mnt /bin  /sbin  ...

  2. 制作linux根文件系统

    转载地址:http://wenku.baidu.com/view/2cb1b4707fd5360cba1adb14.html 2011十一月 24 转 嵌入式根文件系统制作 (3985) (0) 转自 ...

  3. linux根文件系统制作

    在嵌入式中移植的内核下载到开发板上,是没有办法真正的启动Linux操作系统的,会出现无法加载文件系统的错误. 那么根文件系统在系统启动中到底是什么时候挂载的呢?先将/dev/ram0挂载,而后执行/l ...

  4. linux根文件系统 /etc/resolv.conf 文件详解

    Linux根文件系统/etc/resolv.conf文件,它是DNS客户机配置文件,用于设置DNS服务器的IP地址及DNS域名,还包含了主机的域名搜索顺序.该文件是由域名解析器(resolver,以恶 ...

  5. linux根文件系统制作之busybox编译和系统构建【转】

    转自:http://blog.chinaunix.net/uid-29401328-id-5019660.html 介绍完相关文件后我们开始构建文件系统,涉及到的文件等到具体用到的时候再讲. 一.编译 ...

  6. 使用BusyBox制作嵌入式Linux根文件系统

    STEP 1:构建目录结构  创建根文件系统目录,主要包括以下目录/dev  /etc /lib  /usr  /var /proc /tmp /home /root /mnt /bin  /sbin ...

  7. linux根文件系统制作,busybox启动流程分析

    分析 busybox-1.1.6 启动流程,并 制作一个小的根文件系统 源码百度云链接:https://pan.baidu.com/s/1tJhwctqj4VB4IpuKCA9m1g 提取码 :l10 ...

  8. Linux根文件系统的制作

    转载:http://www.cnblogs.com/hnrainll/archive/2011/06/09/2076655.html 1. 根文件系统 文件系统是包括在一个磁盘(包括光盘.软盘.闪盘及 ...

  9. Linux 根文件系统制作

    1.创建根文件目录 mkdir rootfs(名字是随便取的) 2.创建子目录 cd rootfs mkdir bin dev etc lib proc sbin sys usr mnt tmp va ...

随机推荐

  1. UVALive 7040 Color

    题目链接:LA-7040 题意为用m种颜色给n个格子染色.问正好使用k种颜色的方案有多少. 首先很容易想到的是\( k * (k-1)^{n-1}\),这个算出来的是使用小于等于k种颜色给n个方格染色 ...

  2. mysql 安装和配置

    mysql 安装: 在命令行输入 sudo apt-get install mysql-server  安装过程中会跳出来一个窗口,输入数据库root用户的密码(必须输入密码) 安装完成后 通过 my ...

  3. 将Sphinx的日志放置到/dev/shm里需要注意的事情

    可以采用定时器控制,清空日志的办法: 几种快速清空文件内容的方法: $ : > filename #其中的 : 是一个占位符, 不产生任何输出. $ > filename $ echo “ ...

  4. Thinking in java基础之集合框架(转载)

    集合简介(容器)把具有相同性质的一类东西,汇聚成一个整体,就可以称为集合,例如这里有20个苹果,我们把每一个苹果当成一个东西(一个对象),然后我们借用袋子把这20个苹果装起来,而这个袋子就是集合(也叫 ...

  5. 熟悉并了解uml的使用(一)

    本资料对UML各种模型图的构成和功能进行说明,通过本资料的学习达到可以读懂UML模型图的目的.本资料不涉及模型图作成的要点等相关知识. UML简介 UML (Unified Modeling Lang ...

  6. HP自动检查html标签是否闭合

    function HtmlClose($body) { $strlen_var = strlen($body); // 不包含 html 标签 if (strpos($body, '<') == ...

  7. oracle常用函数整理

    oracle常用函数整理    1.绝对值.取余.判断数值正负函数    绝对值:ABS(n)        示例: SELECT ABS(100),ABS(-100),ABS('100') FROM ...

  8. mysql索引之七:组合索引中选择合适的索引列顺序

    组合索引(concatenated index):由多个列构成的索引,如create index idx_emp on emp(col1, col2, col3, ……),则我们称idx_emp索引为 ...

  9. Bzoj1101 Zap(莫比乌斯反演)

    题面 Bzoj 题解 先化式子 $$ \sum_{x=1}^a\sum_{y=1}^b\mathbf f[gcd(x,y)==d] \\ = \sum_{x=1}^a\sum_{y=1}^b\sum_ ...

  10. SublimeCodeIntel代码自动补全配置

    主要使用python3,所有配置以python3为例.其他语言同理.利用sublimeCodeIntel插件可以实现自动提示python3代码.跳转追踪自定义函数.查看系统函数等.功能还是相当强大的. ...