转自:http://blog.chinaunix.net/uid-26073752-id-1754449.html
busybox 的init主要用于嵌入式系统,所以没有运行级别。
::respawn:-/bin/login -froot 自动作为root用户登录。
在Linux内核中找到/init/main.c 看到如下内容:
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
这里就是执行系统的启动,当满足上面其中之一后,系统就会执行启动进程。一般通过busybox编译后的init在/sbin/下,所以通过第一条命令,下面就需要找到init,分析源码。
在busybox源码的/init/init.c中,有#define INITTAB "/etc/inittab"的定义,inittab的作用自不必再说了,系统会根据inittab的提示进行启动加载。但在在解析inittab时,若没有该文件,便会执行新的启动脚本#defineINIT_SCRIPT "/etc/init.d/rcS"。
rcS就是整个系统启动的关键。
在内核初始化完成后,嵌入式linux 文件系统的启动过程主要包含以下几个步骤:
1. 执行/sbin/init 文件
2. 执行/etc/inittab 文件
3. 执行/etc/init.d/rcS 文件
4. 执行挂载文件系统脚本
5. 执行内核模块脚本
6. 执行网络初始化脚本
7. 执行应用程序启动等脚本,如qtopia 的启动
系统启动流程图:
1. 内核启动init
内核启动的最后一步就是启动init 进程,init 进程是由内核启动的第一个(也是唯一一个和)用户进程(进程ID 为1),它根据配置文件决定启动哪些程序,比如某些脚本, 启动shell ,运行用户指定的程序等,,那么init进程又是怎么启动的呢---是由内核调用/sbin/init 文件而启动的,那有人就有人想知道内核是如何找到需要执行的init文件呢。下面看一下内核代码中init/main.c ,如下所示:
static int noinline init_post(void)
{
free_initmem();
unlock_kernel();
mark_rodate_ro();
system_state=SYSTEM_RUNNING;
numa_default_policy();
if(sys_open((const char __user*) “/dev/console”,O_RDWR,0)<0)
printk(KERN_WARNING “Waring :unable to open an initialconsole.\n”);
(void)sys_dup(0);
(void)sys_dup(0);
if(ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING “Failed to execute%s\n”,ramdisk_execute_command);
}
if(execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING “Failed to execute%s\n”,execute_command);
}
run_init_process(“/sbin/init”);
run_init_process(“/etc/init”);
run_init_process(“/bin/init”);
run_init_process(“/bin/sh”);
panic(“No init found . Try passing init=option to kernel.”);
内核启动init 进程的过程如下:
先打开控制台设备/dev/console ,并复制了两个handle, 这样stdout,stdin,stderr都指向/dev/console,这样就打开了标准设备输入,输出,标准错误设备,然后执行几个外部程序。这几个程序中任何一个加载成功就进入了用户态,内核启动就宣告结束。
2. 执行/etc/inittab 文件
当init 启动成功后,需要做的就是分析/etc/inittab 文件并执行它。其内容如下:
# /etc/inittab
::sysinit:/etc/init.d/rcS
# 启动shell 以/dev/ttySAC0 作为控制台
ttySAC0::askfirst:-/bin/sh
# 按下ctrl+alt+del 之后执行的程序,不过在串口控制台中无法输入ctrl+alt+del 组合键
::ctrlaltdel:/sbin/reboot
# 重启关机前执行的程序
::shutdown:/bin/umount -a -r
3. 执行/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
# 网络配置脚本
. /etc/init.d/network.sh
# load zlg_fs
insmod /bin/zlg_fs.ko
insmod /bin/zlg_ffs.ko
mknod /dev/zlg_fsa b 125 0
mknod /dev/zlg_fsa1 b 125 1
mknod /dev/zlg_fsa2 b 125 2
mount -t vfat /dev/zlg_fsa /usr
mount -a
4. 执行/etc/fstab( 挂载文件系统脚本)
在文件 /etc/init.d/rcS 中执行 mount –a 时,就会按照文件 /etc/fstab 内容挂载相应的文件系统.
#device mount-point type options dump fsck order
none /proc proc defaults 0 0
none /dev/pts devpts mode=0622 0 0
tmpfs /dev/shm tmpfs defaults 0 0
(1)device : 要挂接的设备,如 /dev/hda2
mount-point: 挂接点
type: 文件系统类型,如 pro,jffs2,nfs
options: 挂接参数,以逗号隔开
dump 和 fsck order :用来决定控制 dump,fsck 程序的行为。
5. 接着就会执行一些内核模块和网络俄配置脚本,最后执行应用程序启动等脚本,如 qtopia 的启动。