Linux系统启动之INIT进程和system v init
一. Linux系统启动之INIT进程和system v init
1. 首先介绍一下INIT进程
init进程在Start_kernel执行完毕之后,也就是Kernel初始化完毕之后启动,是系统所有进程的起点,内核在完成核内引导以后,即在本线程(进程)空间内加载init程序,它的进程号是1。
如果是使用system v init启动的话,实际上system v init就是一个INIT进程.
2. 接下来介绍一下/etc/inittab文件
init程序需要读取/etc/inittab文件作为其行为指针,inittab是以行为单位的描述性(非执行性)文本,每一个指令行都具有以下格式: id:runlevel:action:process其中id为入口标识符,runlevel为运行级别,action为动作代号,process为具体的执行程序。
id一般要求4个字符以内,对于getty或其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。
runlevel 是init所处于的运行级别的标识,一般使用0-6以及S或s。0、1、6运行级别被系统保留,0作为shutdown动作,1作为重启至单用户模式,6 为重启;S和s意义相同,表示单用户模式,且无需inittab文件,因此也不在inittab中出现,实际上,进入单用户模式时,init直接在控制台(/dev/console)上运行/sbin/sulogin。
在一般的系统实现中,都使用了2、3、4、5几个级别,在Redhat系统中,2表示无NFS支持的多用户模式,3表示完全多用户模式(也是最常用的级别),4保留给用户自定义,5表示XDM图形登录方式。7-9级别也是可以使用的,传统的unix系统没有定义这几个级别。runlevel可以是并列的多个值,以匹配多个运行级别,对大多数action来说,仅当runlevel与当前运行级别匹配成功才会执行。
initdefault 是一个特殊的action值,用于标识缺省的启动级别;当init由核心激活以后,它将读取inittab中的initdefault项,取得其中的 runlevel,并作为当前的运行级别。如果没有inittab文件,或者其中没有initdefault项,init将在控制台上请求输入.
3. 分析一下system v init的流程
>> 首先会执行/etc/rc.d/rc.sysinit,它主要完成启动交换分区/检查磁盘/配置主机名/检查并挂载文件系统/加载并初始化硬件模块等功能;
>> 然后执行缺省的运行级别模式(例如通过id:5:initdefault指定缺省的运行级别为5的话,则会到etc/rc.d/rc5.d目录下寻找并执行所有的配置文件,实际上该目录下的所有配置文件都是链接到/etc/rc.d/init.d目录下的文件,可以通过ls -l命令来查看具体的链接关系);
>> 接下来去执行/etc/rc.d/rc.local脚本文件(这是INIT执行的最后一个脚本文件,所以用户可以在这个文件中添加一些需要在登陆之前执行的命令,作用上和PC电脑windows或者dos系统中c盘根目录下的autoexec.bat作用完全一样);
>> 最后去执行/bin/login程序
如果上述的初始化过程都能够正常结束的话,将为使用者进行初始化环境操作,并将控制权交给shell.
二. 由Linux系统启动之INIT进程和system v init想到的系统开机启动应用程序的调用
通过上面的讲述可以看到,系统的启动过程中init进程会去etc/rc.d/rc*.d目录下寻找并执行默认运行级别的配置文件,显然在这个过程中可以通过添加配置文件来启动我们自己的应用程序.同时,我们也注意到system v init执行流程的第三步中会去检查并执行/etc/rc.d/rc.local脚本文件,可以通过该脚本文件来启动我们自己的应用程序.
所以,我们得到如下的结论:
1. 在启动/etc/init.d下添加启动脚本,创建/etc/rc.d/.../目录下的链接
实际上系统中绝大部分的应用程序都是通过这种方式来进行启动的。
有关脚本的语法和写法不是这里描述的重点,网上资料一大把,去问BAIDU&GOOGLE吧.
2. 直接在/etc/rc.d/rc.local中添加命令,该脚本在启动过程中调用
比如我机器F10上rc.local的内容如下:
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
touch /var/lock/subsys/local
相应的在后面天加上自己要启动的应用程序就可以了,例如有些example中使用如下的方式启动nfs:/etc/rc.d/init.d/nfs restart (注释以下,restart为调用脚本时候的参数)
通过查询资料,突然想起来可以通过u-boot或者类似的boot程序给kernel传递参数,通过参数来指定启动的应用程序名字及其路径,例如init=/passion's program(注释:这只是参数的一部分,完整的参数还有其它的内容,可以参照boot代码或者kernel参数的相关介绍).只不过,这个时候启动应用程序的时间和上面的两种方法不太一样,这个是在kernel初始化刚结束的时候启动的,就是在system v init还没有启动的时候调用的.当然了,上面的两种方法启动的应用程序的也不是在同一时刻进行调用.
好了,收工.