对于mini2440,虽然root_qtopia这个文件系统的GUI是基于Qtopia的,但其初始化启动过程却是由大部分由busybox完成,Qtopia(qpe)只是在启动的最后阶段被开启。

由于默认的内核命令行上有init=/linuxrc,
因此,在文件系统被挂载后,运行的第一个程序是根目录下的linuxrc。这是一个指向/bin/busybox的链接,也就是说,系统起来后运行的第一
个程序也就是busybox本身。这种情况下,busybox首先将试图解析/etc/inittab来获取进一步的初始化配置信息(参考busybox
源代码init/init.c中的parse_inittab()函数)。而事实上,root_qtopia中并没有/etc/inittab这个配置文
件,根据busybox的逻辑,它将生成默认的配置(部分):

static void parse_inittab(void)
{
#if ENABLE_FEATURE_USE_INITTAB
      
char *token[4];
       
parser_t *parser = config_open2("/etc/inittab",
fopen_for_read);
 
       
if (parser == NULL)
#endif
       
{

new_init_action(CTRLALTDEL, "reboot", "");

new_init_action(SHUTDOWN, "umount -a -r", "");

if (ENABLE_SWAPONOFF)
                       
new_init_action(SHUTDOWN, "swapoff -a", "");

new_init_action(RESTART, "init", "");

new_init_action(ASKFIRST, bb_default_login_shell, "");
//TODO: VC_1 instead of ""? "" is console -> ctty
problems -> angry users
               
new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
               
new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
               
new_init_action(ASKFIRST, bb_default_login_shell, VC_4);

new_init_action(SYSINIT, INIT_SCRIPT, "");
               
return;
       
}
……
其中, 最重要的一个,就是new_init_action(SYSINIT, INIT_SCRIPT, ""),
也就决定了接下去初始化的脚本是INIT_SCRIPT所定义的值。这个宏的默认值是"/etc/init.d/rcS"。
下面是文件系统中/etc/init.d/rcS的内容, 也是我们要分析的重点

#! /bin/sh
 
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
 
#
#      
Trap CTRL-C &c only in this shell so we can
interrupt subprocesses.
#
trap ":" INT QUIT TSTP
/bin/hostname FriendlyARM
 
/bin/mount -n -t proc none /proc
/bin/mount -n -t sysfs none /sys
/bin/mount -n -t usbfs none /proc/bus/usb
/bin/mount -t ramfs none /dev
 
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
/bin/hotplug
 
# mounting file system specified in /etc/fstab
mkdir -p /dev/pts
mkdir -p /dev/shm
/bin/mount -n -t devpts none /dev/pts -o mode=0622
/bin/mount -n -t tmpfs tmpfs /dev/shm
/bin/mount -n -t ramfs none /tmp
/bin/mount -n -t ramfs none /var
mkdir -p /var/empty
mkdir -p /var/log
mkdir -p /var/lock
mkdir -p /var/run
mkdir -p /var/tmp
 
/sbin/hwclock -s
 
syslogd
/etc/rc.d/init.d/netd start
echo "  " > /dev/tty1
echo "Starting networking..." > /dev/tty1
sleep 1
/etc/rc.d/init.d/httpd start
echo
"    
" > /dev/tty1
echo "Starting web server..." > /dev/tty1
sleep 1
/etc/rc.d/init.d/leds start
echo "  " > /dev/tty1
echo "Starting leds service..." > /dev/tty1
echo
"                       
"
sleep 1
 
/sbin/ifconfig lo 127.0.0.1
/etc/init.d/ifconfig-eth0
 
/bin/qtopia &
echo
"                                 
" > /dev/tty1
echo "Starting Qtopia, please waiting..." >
/dev/tty1
下面就逐个来分析:
1.         
启动环境设置必要的环境变量;
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin: runlevel=S
prevlevel=N umask 022 export PATH runlevel prevlevel
2.         
设置机器名字;
/bin/hostname FriendlyARM
3.         
挂载“虚拟”文件系统,
/bin/mount -n -t proc none /proc
/bin/mount -n -t sysfs none /sys
/bin/mount -n -t usbfs none /proc/bus/usb
/bin/mount -t ramfs none /dev
这里是挂载/proc, /sys,并且在/dev目录上挂载一个ramfs,相当于把原本NAND
Flash上的只读的/dev目录“覆盖”上一块可写的空的SDRAM。
这里要注意的是,/sys和挂载了ramfs的/dev是正确创建设备节点的关键。对于2.6.29内核来说,已经没有了devfs的支持,创建设备节点只有通过两种办法由文件系统完成:

1)
制作文件系统镜像前用mknod手动创建好系统中所有的(包括可能有的)设备节点,并把这些节点文件一起做进文件系统镜像中;
2)在文件系统初始化过程中,通过/sys目录所输出的信息,在/dev目录下动态的创建系统中当前实际有的设备节点。
显然,方法1)有很大的局限性,仅限于没有设备动态增加或减少的情况,不适用于很多设备热插拔的情况,比如U盘,SD卡等等。方法2)是目前大多数PC上Linux的做法(基于udev实现)。这种方法有两个前提:/sys目录挂载和一个可写的/dev目录。

这也就是为什么我们在这里需要挂载/sys和ramfs在/dev目录上。事实上,这种方法最早就是为热插拔设计的,你可以理解为当系统启动是,所有设备一下子全部“插入”了进来。

这里有一点要说明的是,在文件系统初始化跑到这里之前,原本的/dev目录下必须有一个的设备节点:/dev/console。
4.         
支持热插拔
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev –s
/bin/hotplug
这几个就是用来完成我上面所说的两个东西:
1)通过mdev -s 在/dev目录下建立必要的设备节点;
2)设置内核的hotplug handler为mdev, 即当设备热插拔时,由mdev接收来自内核的消息并作出相应的回应,
比如挂载U盘。
对于mdev,需要注意的是,文件系统里存在/etc/mdev.conf文件,它包含了mdev的配置信息。通过这个文件,我们可以自定义一些设备节点的名称或链接来满足特定的需要。这是root
qtopia中mdev.conf的内容:

# system all-writable
devices

full           
0:0    
0666
null           
0:0    
0666
ptmx           
0:0    
0666
random         
0:0    
0666
tty            
0:0    
0666
zero           
0:0    
0666
 
# console devices
tty[0-9]*      
0:5    
0660   
vc/[0-9]*      
0:5    
0660   
 
# serial port devices
s3c2410_serial0
0:5    
0666   
=ttySAC0
s3c2410_serial1
0:5    
0666   
=ttySAC1
s3c2410_serial2
0:5    
0666   
=ttySAC2
s3c2410_serial3
0:5    
0666   
=ttySAC3
 
# loop devices
loop[0-9]*     
0:0    
0660   
=loop/ 
 
# i2c devices
i2c-0          
0:0    
0666   
=i2c/0 
i2c-1          
0:0    
0666   
=i2c/1 
 
# frame buffer devices
fb[0-9]        
0:0    
0666   
 
# input devices
mice           
0:0    
0660   
=input

mouse.*        
0:0    
0660   
=input/
event.*        
0:0    
0660   
=input/
ts.*           
0:0    
0660   
=input/
 
# rtc devices
rtc0           
0:0    
0644   
>rtc
rtc[1-9]       
0:0    
0644
 
# misc devices
mmcblk0p1      
0:0    
0600    =sdcard
*/bin/hotplug.sh
sda1           
0:0    
0600    =udisk *
/bin/hotplug.sh
可以看到,原本串口驱动注册的设备名是s3c2410_serial0,s3c2410_serial1和s3c2410_serial2,而mdev则会在/dev目录下对应生成ttySAC0,ttySAC1和ttySAC2以符合应用程序对于串口设备名称的习惯。

同样的,/dev/sdcard和/dev/udisk永远分别指向SD卡和U盘的第一个分区。(所以,用那些没有分区表的SD卡或U盘的兄弟知道原因了吧...)

5.         
挂载一些其它的常用文件系统
# mounting file system specified in /etc/fstab
mkdir -p /dev/pts
mkdir -p /dev/shm
/bin/mount -n -t devpts none /dev/pts -o mode=0622
/bin/mount -n -t tmpfs tmpfs /dev/shm
/bin/mount -n -t ramfs none /tmp
/bin/mount -n -t ramfs none /var
mkdir -p /var/empty
mkdir -p /var/log
mkdir -p /var/lock
mkdir -p /var/run
mkdir -p /var/tmp
就像注释中所说的,这是用来挂载其他一些常用的文件系统,并在/var目录下(同样是ramfs,可写的)新建必要的目录。
6.         
设定系统时间
/sbin/hwclock -s
从硬件RTC中获取,不过似乎有问题接下来就是启动系统服务了,包括log记录,网络, http
server和自定义的"跑马灯服务"...
【关于mdev.conf的补充说明】
# misc devices
mmcblk0p1 0:0 0600 =sdcard */bin/hotplug
sda1 0:0 0600 =udisk * /bin/hotplug
这两句配置的意思是当SD卡或者U盘插入/拔出时,将这个消息传递给自定义的热插拔handler, /bin/hotplug.
这个程序是友善之臂开发的用于自动挂载可移动设备的,目前是SD卡和U盘。它的逻辑很简单,将SD卡或者U盘的第一个分区作为FAT/FAT32挂载到/sdcard或者/udisk。

但这也同时带来一个问题,当SD卡或者U盘上没有分区表或者第一个分区不是FAT/FAT32格式的时候,它就玩不转了,兄弟们要小心了:)

7.         
启动一系列服务:
Syslogd
/etc/rc.d/init.d/netd start
echo " " > /dev/tty1
echo "Starting networking..." > /dev/tty1
sleep 1
/etc/rc.d/init.d/httpd start
echo " " > /dev/tty1
echo "Starting web server..." > /dev/tty1
sleep 1
/etc/rc.d/init.d/leds start
echo " " > /dev/tty1
echo "Starting leds service..." > /dev/tty1
echo " "
sleep 1
n   syslog -
用于记录内核和应用程序debug信息
n   netd - inetd,
一个挂载启动各种网络相关服务的看守进程
n   httpd - http server看守进程
n   leds- 跑马灯看守进程
其中,inetd的配置文件为/etc/inetd.conf,这是文件内容:

# /etc/inetd.conf:  see inetd(8) for further
informations.
echo    
stream 
tcp   
nowait 
root   
internal
echo    
dgram  
udp   
wait   
root   
internal
daytime  stream 
tcp   
nowait 
root   
internal
daytime  dgram  
udp   
wait   
root   
internal
time    
stream 
tcp   
nowait 
root   
internal
time    
dgram  
udp   
wait   
root   
internal
 
# These are standard services.
#
ftp    
stream 
tcp    
nowait 
root   
/usr/sbin/ftpd         
/usr/sbin/ftpd
telnet  stream 
tcp    
nowait 
root   
/usr/sbin/telnetd      
/usr/sbin/telnetd -i
可以看到,这里启动的网络服务有两个:
1)ftp server 和
2)telnet server。
有关网络服务的端口和协议等具体信息,可以参考/etc/services, /etc/protocol。
8.         
配置网络设备(网卡)
/sbin/ifconfig lo 127.0.0.1/etc/init.d/ifconfig-eth0:
1)设定本机回环地址为127.0.0.1
2)运行网卡设置脚本/etc/init.d/ifconfig-eth0
这是/etc/init.d/ifconfig-eth0的内容, 加入了我的一些注释
#!/bin/sh
echo -n Try to bring eth0 interface
up......>/dev/ttySAC0
#判断/etc/eth0-setting文件是否存在
if [ -f /etc/eth0-setting ] ; then
#读取配置文件信息
source /etc/eth0-setting
#如果根文件系统为nfs,则说明网卡已经配置OK,这里什么都不需要配置了
if grep -q "^/dev/root / nfs " /etc/mtab ; then echo -n NFS root
... > /dev/ttySAC0
#否则,根据配置文件中的MAC, IP, Mask和Gateway通过ifconfig命令相应地配置网卡
else
ifconfig eth0 down
ifconfig eth0 hw ether $MAC
ifconfig eth0 $IP netmask $Mask up
route add default gw $Gateway fi
#将配置文件中的DNS设置写入/etc/resolv.conf使之生效
echo nameserver $DNS > /etc/resolv.conf
#配置文件不存在,使用默认配置else
#如果根文件系统为nfs,则说明网卡已经配置OK,这里什么都不需要配置了
if grep -q "^/dev/root / nfs " /etc/mtab ; then
echo -n NFS root ... > /dev/ttySAC0
else
#将网卡的IP地址设定为192.168.1.230
/sbin/ifconfig eth0 192.168.1.230 netmask 255.255.255.0 up
fi
fi
echo Done > /dev/ttySAC0
可以看到,NFS自动识别就是靠判断/etc/mtab中是否有nfs的挂载记录实现的。
这是root qtopia文件系统中/etc/eth0-settings文件:
IP=192.168.1.230
Mask=255.255.255.0
Gateway=192.168.1.1
DNS=192.168.1.1
MAC=08:90:90:90:90:90
终于到最后了,启动Qtopia GUI环境
/bin/qtopia &
echo " " > /dev/tty1
echo "Starting Qtopia, please waiting..." >
/dev/tty1
可以看到,这里Qtopia是通过运行/bin/qtopia来启动的。事实上,/bin/qtopia也是一个脚本,它的任务是设定Qtopia运行必要的环境,
最后通过调用qpe可执行文件真正启动Qtopia。这是它的全部内容,我加入了一些注释:

#!/bin/sh
 
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CONFFILE=/usr/local/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/local/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export QTDIR=/opt/Qtopia
export QPEDIR=/opt/Qtopia
export PATH=$QTDIR/bin:$PATH
export
LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH
 
 
TS_INFO_FILE=/sys/devices/virtual/input/input0/uevent
if [ -e $TS_INFO_FILE -a "/bin/grep -q TouchScreen <
$TS_INFO_FILE" ]; then
       
export QWS_MOUSE_PROTO="TPanel:/dev/input/event0
USB:/dev/input/mice"
       
if [ -e /etc/pointercal -a ! -s /etc/pointercal ] ; then
               
rm /etc/pointercal
       
fi

else
       
export QWS_MOUSE_PROTO="USB:/dev/input/mice"
       
>/etc/pointercal
fi
unset TS_INFO_FILE
 
export QWS_KEYBOARD=TTY:/dev/tty1
export KDEDIR=/opt/kde
 
export HOME=/root
 
exec $QPEDIR/bin/qpe 1>/dev/null
2>/dev/null
#!/bin/sh
#(1)tslib环境变量设置,包括了touchscreen设备文件,tslib配置文件,tslib
plug-in位置和touchscreen校准数据文件
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CONFFILE=/usr/local/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/local/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
#(2)Qtopia环境变量设置,设定了Qtopia主要文件位置
export QTDIR=/opt/Qtopia
export QPEDIR=/opt/Qtopia
#(3)设定PATH和LD_LIBRARY_PATH以包含Qtopia的可执行文件和共享库文件,方便Qtopia正确运行
export PATH=$QTDIR/bin:$PATH
export
LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH
#(4)通过判断/sys/devices/virtual/input/input0/uevent中是否包含touchscreen信息使Qtopia自动识别touchscreen和USB鼠标

TS_INFO_FILE=/sys/devices/virtual/input/input0/uevent
if [ -e $TS_INFO_FILE -a "/bin/grep -q TouchScreen <
$TS_INFO_FILE" ]; then
export QWS_MOUSE_PROTO="TPanel:/dev/input/event0
USB:/dev/input/mice"
if [ -e /etc/pointercal -a ! -s /etc/pointercal ] ; then
rm /etc/pointercal
fi
else
export QWS_MOUSE_PROTO="USB:/dev/input/mice"
>/etc/pointercal
fi
unset TS_INFO_FILE
export QWS_KEYBOARD=TTY:/dev/tty1export KDEDIR=/opt/kde
export HOME=/root
#(5)通过调用/opt/Qtopia/bin/qpe真正启动Qtopia
exec $QPEDIR/bin/qpe 1>/dev/null
2>/dev/null
到此为止,文件系统从初始化到最终启动Qtopia
GUI环境的全部过程就结束了。大家可以看到,友善之臂的“小秘密”其实都在这里,说穿了很简单:)只要大家能够静下心来认真看看脚本,看看源代码,加上一些背景知识的了解,搞清楚一个嵌入式系统就这么简单。

通常/linuxrc这个文件只有在
1. 使用了Initial Ramdisk (initrd)
2. 内核命令行上指定了init=/linuxrc
这两种情况下才有用,mini2440的root_qtopia属于情况2),
在root_qtopia中,/linuxrc是指向/bin/busybox的符号链接,也就是说,整个文件系统的入口就变成了busybox的main()函数,busybox支持这种方式来启动busybox本身和整个文件系统的初始化。

【转载】Mini2440启动配置文件说明的更多相关文章

  1. [08]ASP.NET Core 中 launchsettings.json 启动配置文件

    ASP.NET Core launchsettings.json 启动配置文件 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新版本 本文出自 ...

  2. Ubuntu grub2的启动配置文件grub.cfg,为了修改另人生厌的时间

    文章转自http://hi.baidu.com/detax/blog/item/90f18b54a8ef5253d00906e4.html 升级到Ubuntu 9.10后,就要接触grub2了,它和以 ...

  3. 转载~vim配置文件

    转载自:小码哥的博客 花了很长时间整理的,感觉用起来很方便,共享一下. 我的vim配置主要有以下优点: 1.按F5可以直接编译并执行C.C++.java代码以及执行shell脚本,按“F8”可进行C. ...

  4. redis3.2 最新版本启动配置文件redis.conf详细说明

    Redis.conf文件内容详细说明: # 默认redis不是以后台进程的方式启动,如果需要在后台运行,需要将这个值设置成yes # 以后台方式启动的时候,redis会写入默认的进程文件/var/ru ...

  5. [转载] Linux启动过程详解-《别怕Linux编程》之八

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket.为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. = ...

  6. [转载]MySQL5.5 配置文件 my.ini 1067错误

    原文链接:http://blog.csdn.net/xiaochunyong/article/details/7438200 解压mysql-5.5.22-win32.zip后的目录中有5个my-xx ...

  7. Grub启动配置文件

    和许多其他linux发行版一样,Fedora使用Grub作为32位和64位X86系统的启动加载器(bootloader).grub的配置文件主要是/boot/grub/grub.conf,而/boot ...

  8. 【转】嵌入式Linux启动配置文件及脚本

    原文网址:http://blog.csdn.net/shuaishuai80/article/details/6202497 使用Busybox制作根文件系统时,/etc目录非常重要,它包含了嵌入式L ...

  9. 嵌入式Linux启动配置文件及脚本分…

    使用Busybox制作根文件系统时,/etc目录非常重要,它包含了嵌入式Linux启动所需的配置文件及脚本.由于init进程,或者说linuxrc程序会解析inittab文件,因此就从/etc/ini ...

随机推荐

  1. 在Maven中怎么配置外部Jar

    转摘自:http://liugang594.iteye.com/blog/1677712 假设我们有一个Maven的project,其中有些Jar包不是来自Maven库的,是存在本地的某些Jar文件, ...

  2. Redis(1) 初识Redis

    redis介绍: Redis是一个开源(BSD许可)的内存数据结构存储,用作数据库,缓存和消息代理.它支持数据结构,如字符串(String),哈希(Hash),列表(List),集合(Set),具有范 ...

  3. Spring学习-- AOP入门动态代理

    AOP 的拦截功能是由 java 中的动态代理来实现的.说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常 ...

  4. vue入门知识

    vue的特点在于:响应的数据绑定.组合的视图组件. vue的文件,分成三个部分<template>html模板</template>  <script>js< ...

  5. CSS选择器及CSS3新增选择器

    转自:http://www.cnblogs.com/libingql/p/4375354.html 1. CSS1定义的选择器 选择器 类型 说明 E 类型选择器 选择指定类型的元素 E#id ID选 ...

  6. java bigdemical比较大小

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_33451004/article/details/71247041 java中对bigdimic ...

  7. 鼠标DPI和液晶显示器分辨率的关系

    鼠标DPI和液晶显示器分辨率的关系 说起鼠标,有两个性能指标是我们不能忽略的.一是游戏玩家相当熟悉的扫描率(单位:Frames Per Second),二是我们今天要和大家探讨的鼠标的分辨率(单位:D ...

  8. Maven的默认中央仓库以及修改默认仓库&配置第三方jar包从私服下载

    当构建一个Maven项目时,首先检查pom.xml文件以确定依赖包的下载位置,执行顺序如下: 1.从本地资源库中查找并获得依赖包,如果没有,执行第2步. 2.从Maven默认中央仓库中查找并获得依赖包 ...

  9. hashlib,suprocess,configparser模块

    十 hashlib模块 1.什么叫hash:hash是一种算法,该算法接受传入的内容,经过运算得到一串hash值 2.hash值的特点是: 2.1 只要传入的内容一样,得到的hash值必然一样==== ...

  10. TortoiseSVN安装使用【转】

    转自:http://www.cnblogs.com/rushoooooo/archive/2011/04/29/2032346.html TortoiseSVN是windows平台下Subversio ...