根文件系统(rootfs)-4

一、根文件系统的作用
是linux挂载的第一个文件系统,rootfs包含shell命令、linux系统配置文件(文件系统的挂载、网络服务、用户名、主机名、用户密码、环境变量...)、linux应用程序、应用程序处理的数据、独立的驱动模块(*.ko)。


根文件系统,相当于linux内核外围的一个应用环境。


========================================================================================================


二、控制台输出:
[    4.183226] yaffs: dev is 32505860 name is "mtdblock4" rw  //存放rootfs的设备名字mtdblock4 ,rw可读写
[    4.183291] yaffs: passed flags ""
[    4.337878] VFS: Mounted root (yaffs filesystem) on device 31:4.  //31:4 --》主设备:次设备号
[    4.338028] Freeing init memory: 536K  ---->rootfs挂载成功,释放内核中一些初始化函数所占用的内存
[    4.357023] usb 1-1: New USB device found, idVendor=1a40, idProduct=0101
[    4.357083] usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[    4.357145] usb 1-1: Product: USB 2.0 Hub
[    4.357747] hub 1-1:1.0: USB hub found
[    4.357852] hub 1-1:1.0: 4 ports detected
[    5.886184] smdkc110-rtc smdkc110-rtc: rtc disabled, re-enabling
[    6.086924] eth0: link down
[    6.087198] ADDRCONF(NETDEV_UP): eth0: link is not ready
[root@YueQian /]# 
[root@YueQian /]# 
[root@YueQian /]# 
[root@YueQian /]# 


最小的根文件系统的内容:
# ls /
bin         home        media       proc        sys         usr
dev         lib         mnt         root        tmp         var
etc         lost+found  opt         sbin  






========================================================================================================
三、根文件系统启动过程  
1、uboot的启动参数:
init=/linuxrc
   init是linux运行时的第一个进程,该进程执行的是/linuxrc    其中linuxrc -> bin/busybox 
        init=/sbin/init    其中:init -> ../bin/busybox 


--------------------------------------------------------------------------------------------------------
2、内核启动后,首先通过vfs去挂在rootfs,然后再执行init=/linuxrc ,linuxrc是busybox这个工作生成的文件。
linuxrc最后去分析一个rootfs下的一个文件/etc/inittab文件


--------------------------------------------------------------------------------------------------------
3、/etc/inittab


::sysinit:/etc/init.d/rcS   #系统初始化的时候,调用的一个脚本文件
::respawn:-/bin/sh          #系统启动后,进入一个shell环境
::restart:/sbin/init        #系统复位以后,重新执行/sbin/init
#::once:/etc/rc.local
::shutdown:/bin/umount -a -r  #关机的时候,做所有挂载的解压




注意:inittab文件的格式:
id:runlevel:action:process
其中:
--id:用来指定所启动进程的控制台,在嵌入式系统中一般不添;
--runlevel:busybox 完全忽略 runlevel 字段;
--action:指出 init 程序在执行相应 process 时,对 process 所采取的动作。: Valid actions
include: sysinit, respawn, askfirst, wait, once, restart, ctrlaltdel, and shutdown.
--process:具体的执行程序或者脚本;


根据inittab文件,得到系统在初始化启动的时候,执行/etc/init.d/rcS脚本,其中rcS我们可以修改




--------------------------------------------------------------------------------------------------------
4、/etc/init.d/rcS


#!/bin/sh  #shell脚本文件


1)声明了linux系统的基本的环境变量
PATH=/sbin:/bin:/usr/sbin:/usr/bin  #定义系统shell命令的路径
runlevel=S  #single
prevlevel=N #没有前级
umask 022   #创建文件  得到的文件权限 = 声明的权限 & (~umask)
export PATH runlevel prevlevel  #将以上内容声明环境变量中。


2)根据/etc/fstab文件进行文件的挂载
mount -a
#最关键的两个内容:将proc文件系统挂载到/proc目录下,将sysfs文件系统挂载到/sys目录下。否则/proc和/sys目录下都是空。
#/sys路径下是驱动相关的信息,如果sys路径下是空的,/dev路径下也会是空的(/dev是设备驱动的文件)。




3)telnet使用的一个设备文件
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts


4)启动mdev工具
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
#mdev根据/sys路径下的驱动详细信息,然后在/dev下创建设备文件(如:/dev/fb0),如果不使用mdev这个工具,/dev路径下是空的
#/proc/sys/kernel/hotpluy,当linux系统在工作的过程中,我们插入一些设备(安装一些驱动),会系统创建设备文件。


5)不是必要
mkdir -p /var/lock
#mount -t yaffs2 /dev/mtdblock5  /data/


mkdir /dev/fb /dev/v4l
ln -s /dev/fb0 /dev/fb/0
ln -s /dev/video0 /dev/v4l/video0


6)启动硬件的RTC时钟
hwclock -s


7)网络配置IP
ifconfig lo 127.0.0.1  #网络回环
ifconfig eth0 192.168.0.103  #dm9000网卡


8)启动应用程序
#qtopia &
#source qt4 &


9)设置主机名
/bin/hostname  GEC210


注意:/etc/init.d/rcS文件我们是可以修改的,可以根据自己的需要增加内容。


--------------------------------------------------------------------------------------------------------
5、/etc/profile
#!/bin/sh
# Ash profile
# vim: syntax=sh


# No core files by default


1)声明系统的环境变量
ulimit -S -c 0 > /dev/null 2>&1


USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]\# '
PATH=$PATH


HOSTNAME=`/bin/hostname`


export USER LOGNAME PS1 PATH


2)启动无线wifi
ifconfig wlan0 up


3)向环境变量中,声明tslib库。
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_CONFFILE=/tslib/etc/ts.conf
export TSLIB_CONSOLEDEVICE=none
export POINTERCAL_FILE=/etc/pointercal
export TSLIB_CALIBFILE=/tslib/etc/pointercal
export QWS_MOUSE_PROTO=TPanel:/dev/event0
export QTDIR=/opt/Qtopia
export QPEDIR=/opt/Qtopia
export PATH=$QTDIR/bin/:$PATH
export CAMERA_DEVICE=/dev/video3
export V_ROOT=/tslib
export QWS_KEYBOARD=TTY:/dev/tty1
export PATH=/bin:/usr/bin:$PATH
export TSLIB_PLUGINDIR=/tslib/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export QWS_DISPLAY=:1
export PATH=$QPEDIR/bin:$PATH
export LD_LIBRARY_PATH=$V_ROOT/lib:/lib:/usr/lib:$LD_LIBRARY_PATH


export TSLIB_CALIBFILE=/etc/pointercal  #触摸屏校正后的数据文件
export HOME=/root
export KDEDIR=/opt/kde                                           
export QWS_KEYBOARD="TTY:/dev/tty1"                              
export PATH=$QPEDIR/bin:/tslib/bin:$PATH
export LD_LIBRARY_PATH=/tslib/lib:/opt/Qtopia/lib:$QPEDIR/lib
export QWS_MOUSE_PROTO="TPanel:/dev/event0 Tslib"
#MouseMan:/dev/mice                                          


4)安装声卡驱动                                                             
modprobe snd-soc-wm8960                                      
modprobe snd-soc-gec210-wm8960                                   




5) 做触摸屏的校正                                                                
if [ -f /etc/pointercal ] ; then                                 
          hotplug                                                
else                                                             
          /tslib/bin/ts_calibrate  #执行触摸屏的校正程序                               
          hotplug                       
fi


6)执行一个用户脚本文件                                                           
source upiot.sh 




注意:
一般情况下,linux系统启动后,我们想自动运行一个应用程序或者安装一些驱动模块(*.ko), 
在/etc/profile文件中,调用以上内容 。




------------------------------------------------------------------------------------------------------
6、执行一个用户脚本:upiot.sh


source /IOT/driver/auto.sh
cd  /IOT/
./iot -qws&   #后台运行一个QT应用程序
cd /


------------------------------------------------------------------------------------------------------
7、执行一个用户脚本:/IOT/driver/auto.sh


安装物联网测试平台的驱动
insmod /IOT/driver/adc_drv.ko
#insmod /IOT/driver/buttons_drv.ko
insmod /IOT/driver/buzzer_drv.ko
#insmod /IOT/driver/led_drv.ko
insmod /IOT/driver/second.ko
insmod /IOT/driver/timer_irq.ko
insmod /IOT/driver/ov9650.ko
#insmod /IOT/driver/keypad.ko
insmod /IOT/driver/humidity.ko




------------------------------------------------------------------------------------------------------
8、执行物联网的QT程序


./iot -qws&


应用程序程序是一个多任务的程序,是一个死循环。

**********************************************************************************************************************************************

根文件系统制作

一、思路
完成rootfs时,主要是实现根文件系统下的各个文件。rootfs中的内容在开发过程中,是可以逐步根据应用添加的。


# ls /
bin         home        media       proc        sys         usr
dev         lib         mnt         root        tmp         var
etc         opt         sbin  




======================================================================================================
二、制作过程


1、使用busybox工具可以完成shell命令的制作
   busybox实现init进程调用的一个应用:
/bin
/sbin
/usr/bin
/usr/sbin
/linuxrc


1)下载busybox源码:
      http://www.busybox.net/downloads/


2)配置交叉编译工具链
   注意:
       busybox源码包不能在window和linux共享的目录下做。
   
    $ sudo tar -jxvf busybox-1.23.2.tar.bz2 
    $vi Makefile
        CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
        ARCH = arm


3)配置-->选择一些shell命令和工具
    #make menuconfig


4)编译
    #make


5)安装工具
    #make install


在busybox源码包的根目录下有个_install目录。






-----------------------------------------------------------------------------------------
2、向rootfs中添加动态库(so)
/lib


1)我们要从交叉编译工具链中把最基础的动态库拷贝到/lib下
2)我们也使用一些库(libjpeg)的源码包,编译生成动态库,该库也要放在lib目录下


方法如下:
# cp /usr/local/arm/arm-2009q3/arm-none-linux-gnueabi/libc/armv4t/lib/*so* lib -rdf
# arm-none-linux-gnueabi-strip lib/*so*


问题:
    我们自己编译的一个应用程序,如何知道该程序需要哪些动态库??


静态编译:
#gcc -o hello hello.c -static




动态编译:
#gcc -o hello hello.c




$file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped


$ arm-none-linux-gnueabi-readelf  -d hello


 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]


-----------------------------------------------------------------------------------------
3、/dev目录下内容--->设备文件:linux应用程序访问驱动程序的接口
/dev


在/dev下需要预先创建两个设备文件,该两个文件是内核在启动过程中使用的,所以要预先创建
#mknod console c 5 1
#chmod 777 console
mknod null c 1 3
chmod 777 null


/dev目录下的其他的设备文件是mdev工具根据/sys目录下的设备驱动信息自动创建


-----------------------------------------------------------------------------------------
4、/proc和/sys目录下内容
/proc
/sys


1)/proc
实时反映了linux系统的工作状态,/proc挂载proc文件系统。/proc目录在制作根文件系统的时候是空的。


2)/sys
实时反映了linux系统中设备驱动的信息,/sys挂载sysfs文件系统。/sys目录在制作根文件系统的时候是空的。


-----------------------------------------------------------------------------------------
5、/etc下的内容
# ls /etc/
Wireless             inittab              protocols
boa                  login.defs           rc.d
fstab                mdev.conf            resolv.conf
ftpchroot            mime.types           services
ftpusers             net.conf             sysconfig
group                nettype.conf         ts.conf
host.conf            passwd               udisk
hosts                pointercal           wpa_supplicant.conf
inetd.conf           ppp
init.d               profile


/etc是linux系统运行的时候,一些配置文件,这些文件需要自己创建,或者从其他rootfs包中拷贝。


/etc下的关键文件:
1)/etc/inittab
2)etc/init.d/rcS
3)etc/fstab
4)etc/profile
5)etc/resolv.conf
6)etc/inetd.conf
7)etc/sysconfig/HOSTNAME
8)etc/passwd、etc/group、etc/shadow
9)etc/mdev.conf
10)etc/hotplug/usb/udisk_insert
    etc/hotplug/usb/udisk_remove
    etc/hotplug/sd/sd_insert
    etc/hotplug/sd/sd_remove
-----------------------------------------------------------------------------------------
6、其他目录的创建
/home
/root
/var
/mnt
/media
/tmp
/opt


以上目录都是空的,可以根据实际的使用情况在添加。






======================================================================================================
三、rootfs如何挂载使用
1、通过nfs挂载rootfs文件(ubuntu中)
首要条件:
在ubuntu上安装nfs服务器。


1)查看nfs的挂载目录
$ showmount -e
Export list for ubuntu:
/opt/target *


2)将rootfs文件包拷贝到/opt/target目录下
$ pwd
/opt/target/mini_rootfs


3)修改uboot的启动参数
# setenv bootargs 'console=ttySAC0,115200 root=/dev/nfs rw nfsroot=192.168.1.6:/opt/target/mini_rootfs ip=192.168.1.4:192.168.1.1::255.255.255.0::eth0:off init=/linuxrc'


4)启动板子:
输出:
[    5.723629]      device=eth0, addr=192.168.1.4, mask=255.255.255.0, gw=255.255.255.255,
[    5.723705]      host=192.168.1.4, domain=, nis-domain=(none),
[    5.723756]      bootserver=192.168.1.1, rootserver=192.168.1.6, rootpath=
[    5.725965] Looking up port of RPC 100003/2 on 192.168.1.6
[    5.732285] Looking up port of RPC 100005/1 on 192.168.1.6
[    5.741605] VFS: Mounted root (nfs filesystem) on device 0:12.
[    5.741985] Freeing init memory: 536K


Please press Enter to activate this console. 




5)测试:
ls /sys
ls /proc
ls /dev
./hello






2、挂在nand中的rootfs映像:
先将rootfs根文件系统文件进行打包生成rootfs.img, 再将该包烧写到nand中。)


1)使用一个打包的工具:将roofs的文件,打包成yaffs2文件系统格式的一个文件包
(1)编译源码包,生成工具
# tar xvf yaffs2-source.tar
# cd yaffs2/utils
# make 
# cp mkyaffs2image /usr/local/bin/


(2)对rootfs进行打包
# mkyaffs2image mini_rootfs rootfs.img


2)将rootfs.img烧写到nand flash




3)修改启动参数
# setenv bootargs 'console=ttySAC0,115200 root=/dev/mtdblock4 rw rootfstype=yaffs2 init=/linuxrc'






======================================================================================================
四、问题分析
1、注意内核移植的时候,是否选择了nfs服务
没有找到/dev/nfs
见《内核的移植文档》




2、确认启动参数是否正确
服务IP
本地IP
nfs的挂在目录是否正确


3、将rootfs中/etc/init.d/rcS文件中:
ifconfig eth0 192.168.1.4   #本地IP


4、确认ubuntu nfs服务器的挂载目录
#showmount -e


5、修改 /opt/target/mini_rootfs文件的权限
#sudo chmod 777 /opt/target/mini_rootfs -R


6、Please press Enter to activate this console. 
将:
::askfirst:-/bin/sh 
改成:
::respawn:-/bin/sh 





你可能感兴趣的:(构建)