嵌入式linux系统启动分析

2019-07-12 19:51发布

1.1          系统启动
1.1.1        内核启动参数
1.1.1.1.1  Linux内核在启动的时候,能接收某些命令行选项或启动时参数。当内核不能识别某些硬件进而不能设置硬件参数或者为了避免内核更改某些参数的值,可以通过这种方式手动将这些参数传递给内核。
TPX20系统的内核命令串为:root=1f03 rw console=ttyS0,115200 init=/linuxrc。该命令串在内核编译时(make menuconfig)进行设置。
命令串的含义为:
1. init= 设置内核执行的初始化进程名,如果该项没有设置,内核会按顺序尝试/etc/init,/bin/init,/sbin/init, /bin/sh,如果所有的都没找到,内核会抛出 kernel panic:的错误。
2. root= 该参数告诉内核启动时使用哪个设备作为根文件系统。1f03表示mtd设备的第3个分区,即/dev//mtdblock3。
3. ro和rw ro参数告诉内核以只读方式加载根文件系统,以便进行文件系统完整性检查,比如运行fsck;rw参数告诉内核以读写方式加载根文件系统,这是默认值。
1.1.2        初始化进程
1.1.2.1.1  linux内核启动完后,首先执行根目录下的Linuxrc,Linuxrc是用来在安装过程中配置核心的程序,有的是用shell写的,有的是二进制可执行文件,它可以加载模块、引导已安装的系统、恢复系统等。
TPX20系统的linuxrc文件内容如下:
#!/bin/sh
echo "Setting up RAMFS, please wait ... "
/bin/mount -n -t ramfs ramfs /etc/tmp
/bin/mount -n -t ramfs ramfs /etc/var
/bin/mount -n -t ramfs ramfs /root
/bin/mount -a
echo "done and exiting"
exec /sbin/init
1.1.2.1.2             在linuxrc的中,首先加载ramfs文件系统,分别加载目录/etc/tmp,/etc/var,/root。
1.1.2.1.3             命令/bin/mount –a 表示加载文件/etc/fstab文件中的选项。文件/etc/fstab的内容如下:
none                    /proc              proc       defaults                0  0
none            /dev/pts        devpts        mode = 0622       0   0
/dev/mtdblock4   /project            jffs2             defaults              0   0
文件/etc/fstab说明如下:
第一列给出这些文件系统所在的设备。
第二列是加载点的列表。
第三列是标明文件系统的类型。以 proc 开头的那一行是一个特殊的文件系统。
第四列含有一个或以上的加载时的选项。
第五列是给清空工具 (dump utility) 用来决定什么时候进行备份的,很多情况下,您可以在这儿使用0。
第六列是给命令 fsck 使用的,决定在系统启动时的文件系统检查中,应该以什么次序来进行。根文件系统在这项应该使用1,不用进行检查的文件系统应该使用0,其它所有的文件系统应该使用2。
这里加载/proc文件系统和devpts文件系统。这都是linux系统使用的。
请注意的一列的设备/dev/mtdblock4,以jffs2文件系统格式挂载到目录/project中。通过该目录,TPX20系统可以对FLASH进行数据保存。关于/dev/mtdblock的分区方法,请参见本文档的后续章节“FLASH设备驱动”。
1.1.2.1.4             命令exec /sbin/init开始系统的初始化进程。
init程序在终结系统启动程序之前会衍生各种应用程序,并启动若干关键的软件组件。大多数Linux系统使用的init跟System V的init相仿,但对嵌入式Linux系统来说,System V的init过于灵活,极少被使用。在我们的系统中使用的是BusyBox的init。
BusyBox提供有与System V init类似的能力,处理系统的启动工作。BusyBox的 init特别适合在嵌入式系统中使用,因为它可以为嵌入式系统提供所需要的大部分init功能,却不会让嵌入式系统被System V init的额外特性拖累。
因为/sbin/init是/bin/busybox的符号链接,所以BusyBox是目标板系统上执行的第一个应用程序。当BusyBox知道调用它的目的是要执行init,它会立即跳转到init进程。BusyBox的 init进程依次进行以下工作:
1.       为init设置信号处理进程。
2.       初始化控制台。
3.       解析inittab文件(/etc/inittab)。
4.       执行系统初始化命令。
5.       执行所有阻塞的(会导致init暂停的)inittab命令(动作类型:wait)。
6.       执行所有仅执行一次的inittab命令(动作类型:once)。
7.       一旦完成以上工作,init进程便会循环执行以下工作:
8.       执行所有终止时必须重新启动的inittab命令(动作类型:respawn)。
9.       执行所有中止时必须重新启动但启动前必须前询问用户的inittab命令(动作类型:askfirst)。
inittab文件的每一行的格式为:id:runlevel:action:process。process字段用来指定所执行程序的路径,包括命令行选项。action字段用来指定可应用到process的动作。BusyBox init能够识别的inittab动作类型如下表所示:
动作                  结果
sysinit        为init提供初始化命令行的路径
respawn    每当相应的进程终止执行便重新启动
askfirst      类似respawn,不过它的主要用途是减少系统上执行的终端应用程序的数量。它将会促使init在控制台上显示                   “Please press Enter to activate this console.”的信息,并在重新启动进程之前等待用户按下Enter键
wait           告诉init必须等到相应的进程完成才能继续执行
once          仅执行相应的进程一次,而且不会等待它完成
ctrlaltdel    当按下Ctrl-Alt-Delete组合键时,执行相应的进程
shutdown  当系统关机时,执行相应的进程
restart       当init重新启动时,执行相应的进程。通常此处所执行的进程就是init本身           表2-1 inittab动作类型描述 TPX20中,init进程的功能主要体现在inittab文件中,其实现如下:
::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty -L ttyS0 115200 vt100
inittab文件的第一行都是将/etc/init.d/rcS设为系统的初始化文件。init读取/etc/inittab时,首先找出标明sysinit的一行,并执行其后被指定的脚本文件,这个脚本文件通常是一组建立基本系统服务的shell指令。rcS文件的内容如下:
#! /bin/sh
# Set the path
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
# X-hyper255B configration
. /conf/hyper255_config
# Set the hostname.
hostname $HOST_NAME
if [ -f /project/system/etc/rc.local ]; then
 /project/system/etc/rc.local
else
 /etc/init.d/rc.system
fi
这里需要说明的是,语句if [ -f /project/system/etc/rc.local ],它提供了TPX20系统用户升级系统的能力。当需要对系统的应用程序进行更换时,用户只需要把新的应用程序拷贝到/project目录,该目录是JFFS2文件系统,为可写目录。 然后再在目录/project/system/etc/下创建启动脚本文件rc.local即可。