busybox init

linux启动完成后,运行由Busybox产生的init进程。/sbin/init是系统启动的第一个用户进程,pid=1。

init的工作是根据/etc/inittab脚本来进行系统的初始化工作,关机前的工作等。init代码在BusyBox中init/init.c中,主要进行以下工作:

》为init进程设置信号处理进程。

》对控制台进行初始化。

》解析inittab文件即/etc/inittab。

》若无/etc/inittab,采用默认的inittab,运行初始化脚本/etc/init.d/rcS.

》运行inittab中其他命令。

一、inittab

1.1 格式

# Format:
# <id>:<runlevels>:<action>:<process>

id:不可重复,就是一个命令标号,无特殊含义。

runlevels:控制运行模式,单用户、多用户、图形界面等,此版本未使用。

action:包括sysinit、respawn、wait、once、ctrlaltdel、restart等。

》sysinit:为init提供初始化命令行的路径。

》respawn:在紧跟进程结束后,重启启动该进程(后边的process)。--复位,重启

》askfirst:类似respawn,主要用途是减少系统上执行的终端应用程序的数量,

               会在控制台上显示“Please press Enter to active this console"的信息,

               并在系统重启之前等待用户按下”Enter“键。

》wait:通知init必须等到相应的进程执行完之后才能继续执行其他的动作。

》once:进程只执行一次,而且不会等待它完成。

》ctrlaltdel:当按下ctrl-Alt-Del组合键时运行的进程。

》shutdown:当系统关机时运行的进程。

》restart:当init进程重启启动时执行的进程,事实上就是init本身。

process:执行的命令。

# /etc/inittab init(8) configuration for BusyBox
#
# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
#
#
# Note, BusyBox init doesn't support runlevels.  The runlevels field is
# completely ignored by BusyBox init. If you want runlevels, use sysvinit.
#
#
# Format for each entry: <id>:<runlevels>:<action>:<process>
#
# <id>: WARNING: This field has a non-traditional meaning for BusyBox init!
#
#    The id field is used by BusyBox init to specify the controlling tty for
#    the specified process to run on.  The contents of this field are
#    appended to "/dev/" and used as-is.  There is no need for this field to
#    be unique, although if it isn't you may have strange results.  If this
#    field is left blank, then the init's stdin/out will be used.
#
# <runlevels>: The runlevels field is completely ignored.
#
# <action>: Valid actions include: sysinit, respawn, askfirst, wait, once,
#                                  restart, ctrlaltdel, and shutdown.
#
#       Note: askfirst acts just like respawn, but before running the specified
#       process it displays the line "Please press Enter to activate this
#       console." and then waits for the user to press enter before starting
#       the specified process.
#
#       Note: unrecognized actions (like initdefault) will cause init to emit
#       an error message, and then go along with its business.
#
# <process>: Specifies the process to be executed and it's command line.
#
# Note: BusyBox init works just fine without an inittab. If no inittab is
# found, it has the following default behavior:
#         ::sysinit:/etc/init.d/rcS
#         ::askfirst:/bin/sh
#         ::ctrlaltdel:/sbin/reboot
#         ::shutdown:/sbin/swapoff -a
#         ::shutdown:/bin/umount -a -r
#         ::restart:/sbin/init
#         tty2::askfirst:/bin/sh
#         tty3::askfirst:/bin/sh
#         tty4::askfirst:/bin/sh
#
# Boot-time system configuration/initialization script.
# This is run first except when booting in single-user mode.
#
::sysinit:/etc/init.d/rcS

# /bin/sh invocations on selected ttys
#
# Note below that we prefix the shell commands with a "-" to indicate to the
# shell that it is supposed to be a login shell.  Normally this is handled by
# login, but since we are bypassing login in this case, BusyBox lets you do
# this yourself...
#
# Start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# Start an "askfirst" shell on /dev/tty2-4
tty2::askfirst:-/bin/sh
tty3::askfirst:-/bin/sh
tty4::askfirst:-/bin/sh

# /sbin/getty invocations for selected ttys
tty4::respawn:/sbin/getty 38400 tty5
tty5::respawn:/sbin/getty 38400 tty6

# Example of how to put a getty on a serial line (for a terminal)
#::respawn:/sbin/getty -L ttyS0 9600 vt100
#::respawn:/sbin/getty -L ttyS1 9600 vt100
#
# Example how to put a getty on a modem line.
#::respawn:/sbin/getty 57600 ttyS2

# Stuff to do when restarting the init process
::restart:/sbin/init

# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a

不管自己的inittab,还是系统默认inittab,一般首先运行/etc/init.d/rcS脚本,之后再进行后续工作。

bootargs中参数console指定了终端口为ttyS0,所以inittab中console等同于ttyS0,inittab的命令中采用默认终端口执行console或ttyS0。

::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty  115200  tty1
tty2::askfirst:-/bin/sh
tty3::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/bin/umount -a -r

这个inittab执行下列动作:

1)将/etc/init.d/rcS设置成系统的初始化文件

2)在115200 bps的虚拟终端tty1上启动一个登陆会话 (注意getty的用法)

3)在虚拟终端tty2和tty3上启动askfirst动作的shell

4)如果init重新启动,将/sbin/init设置成它会执行的程序

5)告诉init,在系统关机的时候执行umount命令卸载所有文件系统,并且在卸载失败时用只读模式冲新安装以保护文件系统。

1.2 inittab执行顺序

跟踪init/init.c中init的执行流程,可知其工作流程:

在init_mian()中完成inittab解析后,组成init_action[],然后顺序阻塞执行(通过run_actions执行命令):

SYSINIT -> WAIT -> ONCE ->  循环RESPAWN|ASKFIRST

阻塞执行SYSINIT|WAIT|ONCE|CTRLALTDEL|SHUTDOWN -> RESPAWN|ASKFIRST仅执行一次

中间接受到信号(CTRLALTDEL)执行信号处理,一般重启设备。

二、rcS

rcS为系统初始化脚本,完成最开始的一些配置工作,可开启应用程序。

#!/bin/sh

mount -a ;mount文件,要mount的文件有fstab指定。 . /etc/profile ;配置环境变量;可不配置,每个终端启动时都会读取.profile和/etc/profile。 echo "configuring network...\n" ;配置网络 ifconfig eth0 down ifconfig eth0 192.168.1.254 ifconfig lo 127.0.0.1 up route add -net 127.0.0.0 netmask 255.0.0.0 lo route add default gw 192.168.1.1 /usr/sbin/telnetd & ;开启telnet echo "------------rcS over.--------------------\n"

最简单的rcS也应该mount fs,开启网口,telnet,ftp可后续根据需要开启。

fstab配置

#<file name> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
none /tmp ramfs defaults 0 0
sysfs /sys  sysfs defaults 0 0
devpts /dev/pts    devpts defaults 0 0

环境变量profile配置

# /etc/profile: system-wide .profile file for the Bourne shells
echo
echo -n "Processing /etc/profile... "
# no-op
echo "Done"
echo

 

三、相关命令

3.1 getty

linux的登录主要是由两个文件在控制,/usr/sbin/getty来获得用户名,并进行检查用户名是否存在,然后将用户名传递给/usr/bin/login来获取用户输入密码和检查密码是否正确。

所以要实现linux的自动登录,就要改动这两个文件。

getty实现的主要功能是:

1)打开指定的tty;

2)提示用户登录(login:);

3)获得登录用户名;

4)把用户名传递给login命令 。

login实现的主要功能是:

1)先检查是不是超级用户;

2)提示用户输入密码(通过getpass()实现);

3)检查密码并检查是否quiet登录;

4)设置登录的用户的ID和组ID,并设置相应的环境变量。

 

posted @ 2016-08-11 13:49  yuxi_o  阅读(1074)  评论(0编辑  收藏  举报