在内核启动应用程序第二篇中,我们知道,无论内核直接处理默认的配置信息还是先解析配置文件再处理配置信息,都是调用new_init_action这个函数进行处理的。那我们就看一下这个函数具体要做的事情。
一、解析配置文件
首先定义的是几个结构体的变量,我们可以看一下这个结构体的定义:
里面的成员和我们的形参一样,只是多了一个pid的成员,所谓的pid指的是进程号。接着回到new_init_action函数:
706~717,在这个循环里面是说,如果已经保存的参数和传入的参数是一样的,那么就会overwrite,覆盖掉它,然后返回。
接着往下:
718行,如果不满足上面的条件,也就是说传进来的参数在已经保存的链表中找不到,那么就会申请一个内存空间,也就是创建一个init_action结构
接着在这个创建好的init_action结构中,保存传入的参数。
我们可以来小结一下new_init_action这个函数要做的事情:
1、创建init_action结构并填充
2、把这个结构放入init_action_list这个链表中。
二、文件执行的时机
在上面的分析中,我们了解到,内核会先对配置文件进行解析,并且解析后获得的参数保存在init_action_list这个链表中。那么配置文件的信息什么时候才会启动?我们接着回到init.c的main函数看一下:
首先,在inittab中有action的取值:
<action>: Valid actions include: sysinit, respawn, askfirst, wait, once, restart, ctrlaltdel, and shutdown.
然而对每个取值并没有进行说明,所以我们只能在源码看一下,分析run_action这个函数主要做了什么:
对于SYSINIT和WAIT这两个取值,首先执行程序,并且等待执行结束,一旦执行结束后就把它从链表中删除掉。
而对于ONCE这类值,直接执行,不等待执行结束。
接着回到main函数中,进入while死循环:
对于RESPAWN和ASKFIRST这两类值:
wpid = wait(NULL); //等待子进程退出
while (wpid > 0) {
a->pid = 0; //退出后pid设置为0
三、总结:
最小的根文件系统需要以下的条件:
1、 需要dev\console dev\NULL
2、 Init应用程序(一般在busybox中)
3、 程序在运行的时候要读取配置文件/etc/inittab
4、 配置文件中指定的应用程序
5、 C库