Linux根文件之SysV系统启动方式总结

2019-07-13 04:05发布

20130615 1. Linux根文件系统演变 在内核初始化完成后,嵌入式Linux文件系统的启动过程主要包含以下几个步骤: l 执行/sbin/init文件 l 执行/etc/inittab文件 l 执行/etc/rcS文件 l 执行挂载虚拟文件系统脚本 l 执行创建/dev目录文件脚本 l 执行内核模块加载脚本 l 执行网络初始化脚本 l 执行应用程式启动等脚本,如桌面的启动 当init启动成功后,需要做的就是分析/etc/inittab文件并执行它。对于inittab文件,如果使用busyboxinit文件,inittab文件内容与传统的是有区别的: 传统的init:主要应用于PC环境,支持运行级别。 busyboxinit:由于主要用于嵌入式,所有没用运行级别的概念。 概括地讲,Linux/Unix系统一般有两种不同的初始化启动方式. 1) BSD system init 2) System V init   2. Linux根文件系统启动过程及login的实现 2.1 busybox简介 虽然与相应 的GNU工具比较起来,busybox所提供的功能和参数略少,但在比较小的系统(例如启动盘)或者嵌入式系统中,已经足够了。 Busybox配置如下: Build Options---> [*] Build BusyBox as a static binary (no shared libs) Installation Options --->
Login/Password Management Utilities ---> Do you want to build BusyBox with a Cross Compiler。如果要对其他平台进行编译就要选择它并设置相应的编译程序前缀。 Login/Password Management Utilities---> [*]Use internal password and group functions rather than system functions。这里设置使用busybox自己的passwordshadow文件的功能。 如果需要一个交互的登录界面,则选择gettyloginpasswd 编译make TARGET_ARCH=arm,生成的目标代码位于_install目录下。
2. 2文件系统启动过程 Linux的启动过程主要分成两个阶段: 1.启动内核。 2.执行程序initinit程序处理所有程序的启动包括重要系统程序和其它指定在启动时装入的软件。 现在主要详细介绍一下文件系统的启动过程,即linux启动过程的第二阶段,大概分为以下几个过程:   2.2.1运行/etc/inittab init的进程号是1,是系统所有进程的起点。linux在完成核内引导以后,就开始运行init程序。init程序需要 读取配置文件/etc/inittab,以查看下一步做什么。inittab是一个不可执行的文本文件,它有若干行指令所组成,告诉 init 要进入什么运行级别,以及在哪里可以找到该运行级别的配置文件。以下是qsaninittab文件(部分注释省略): # The default runlevel. id:4:initdefault: # Boot-time system configuration/initialization script. # This is run first except when booting in emergency (-b) mode. si::sysinit:/etc/init.d/rcS # /etc/init.d executes the S and K scripts upon change of runlevel. l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l6:6:wait:/etc/init.d/rc 6 # Trap CTRL-ALT-DELETE ca::ctrlaltdel:/sbin/shutdown -t3 -h now # /sbin/getty invocations for the runlevels. # Example how to put a getty on a serial line (for a terminal) T0:134:respawn:/sbin/getty -L ttyS0 115200 vt100 T1:1:respawn:/sbin/getty -L ttyS1 115200 vt100 以上面的inittab文件每一行都有以下格式: id:runlevel:action:process id – 入口标识符。它是一个1-4位的字符串,对于gettymingetty等其他login程序项,要求idtty的编号相同,否则getty程序将不能正常工作。 runlevel – 运行级。一般使用06以及Ss action – 定义init命令应该向进程实施什么动作。包括以下: respawn-无论何时它终止,均重新启动命令 wait-运行命令一次。在继续之前,init等待它终止 once-运行命令一次 boot-命令在启动过程中运行。忽略运行等级字段 bootwait-命令在启动过程中运行,忽略运行等级字段。在继续之前,init等待该进程终止 initdefault-定义Linux系统的默认运行等级 powerwait-停电时命令运行。在继续之前,init等待该进程终止 powerfail-停电时命令运行。在继续之前,init不等待该进程终止 powerokwait-恢复电力时命令运行。在继续之前,init等待该进程终止 powerfailnowUPS发出电池即将耗尽的信号时,运行该命令 process - 是具体的执行程序。程序后面可以带参数。   2.2.2系统初始化 sysinitbootbootwaitaction将在系统启动时无条件运行,而忽略其中的runlevel因此init进程首先会执行etc/init.d/rcS脚本,rcS内容如下: #首先,定义PATHrunlevelprevlevel然后导出到环境中 PATH=/sbin:/bin:/usr/sbin:/usr/bin runlevel=S prevlevel=N umask 022 export PATH runlevel prevlevel #然后,判断是不是第一次安装系统,如果是,则检查并且执行安装程序留下的脚本 if [ -x /sbin/unconfigured.sh ] then   /sbin/unconfigured.sh fi     . /etc/default/rcS export VERBOSE   #捕捉INTQUITTSTP信号, trap":"INT QUIT TSTP   #检查/etc/rcS.d/目录,看是否有以S开头并且紧跟两个字符(实际上 #一般是两个数字099)命名的非普通(! -f"$i")文件,如果有则根据 #文件的类型作出两个选择 # 1,.sh结尾的脚本时执行 # 2,如果不是.sh结尾的脚本,则传递给start参数执行这个文件 for i in /etc/rcS.d/S??* do  # Ignore dangling symlinks for now.  [ ! -f"$i"]&& continue    case"$i"in   *.sh)    # Source shell script for speed.    (     trap - INT QUIT TSTP     set start     . $i    )    ;;   *)    # No sh extension, so fork subprocess.    $i start    ;;  esac done     #这是为了兼容其他系统的/etc/rc.boot脚本 [ -d /etc/rc.boot ]&& run-parts /etc/rc.boot   #这也是用于第一次安装系统后需要执行的脚本,安装成功后,系统上 #一般没有这个脚本 if [ -x /sbin/setup.sh ] then   /sbin/setup.sh fi   #/etc/rc.S/rcS脚本执行结束.返回/inittab
2.2.3启动对应运行级别的守护进程 返回/inittab,启动对应运行级别的守护进程,这里为4init将执行配置文件inittab中的以下这行: l4:4:wait:/etc/init.d/rc 4 /etc/rc.d/rc是一个Shell脚本,它接受4作为参数,去执行/etc/rc.d /rc4.d/目录下的所有的rc启动脚本,/etc/rc.d/rc4.d/目录中的这些启动脚本实际上都是一些链接文件,而不是真正的rc启动脚本, 真正的rc启动脚本实际上都是放在/etc/rc.d/init.d/目录下。   2.2.4建立终端 rc执行完毕后,返回init。这时基本系统环境已经设置好了,各种守护进程也已经启动了。init接下来会打开终端,以便用户登录系统,如以下2行: T0:134:respawn:/sbin/getty -L ttyS0 115200 vt100 T1:1:respawn:/sbin/getty -L ttyS1 115200 vt100 从上面可以看出在134的运行级别中将以respawn方式运行getty程序,它会显示一个文本登录界面,这个界面就是我们经常看到的登录界面,在这个登录界面中会提示用户输入用户名,而用户输入的用户名将作为参数传给login程序来验证用户的身份。 注意:如果想绕过登录验证过程,想直接进入shell界面的话,则把以上两行注释掉,改为:T0:134:respawn:/bin/sh (5)登录系统,启动完成 getty进程接收到用户名后,启动login进程. login进程要求用户输入口令. 用户输入口令. login进程对usernamepassword进行检查. login启动shell进程. shell进程根据/etc/password中的shell类型,启动相应的shell.并启动/etc/profile文件和$HOME/.bash_profile文件.最后出现shell提示符,等待用户输入命令. 至此,启动过程结束。
2.3 login验证过程 Linux的帐号验证程序是login,login会接收getty传来的用户名作为用户名参数。然后login会对用户名进行分析:如果用户名不是root,且存在/etc/nologin文件,login将输出nologin文件的内容,然后退出。这通常用来系统维护时防止非root用户登录。只有/etc/securetty中登记了的终端才允许root用户登录,如果不存在这个文件,则root可以在任何终端上登录。/etc/usertty文件用于对用户作出附加访问限制,如果不存在这个文件,则没有其他限制。 在分析完用户名后,login将搜索/etc/passwd以及/etc/shadow来验证密码以及设置帐户的其它信息,比如:主目录是什么、使用何种shell。如果没有指定主目录,将默认为根目录;如果没有指定shell,将默认为/bin/bash。 login程序成功后,会向对应的终端在输出最近一次登录的信息(在/var/log/lastlog中有记录),并检查用户是否有新邮件(在 /usr/spool/mail/的对应用户名目录下)。然后开始设置各种环境变量:对于bash来说,系统首先寻找/etc/profile脚本文件,并执行它;然后如果用户的主目录中存在.bash_profile文件,就执行它,在这些文件中又可能调用了其它配置文件,所有的配置文件执行后,各种环 境变量也设好了,这时会出现大家熟悉的命令行提示符,到此整个启动过程就结束了。 注:一个最简单的文件系统至少需要包含以下几个目录,/sbin,/bin,/dev(需要console和ttyS0两个文件),/proc,/etc(需要inittab,rcS文件),/home。