企业网站建设软件需求分析,淘宝网网页,个人网站怎么做的模板,网站热销榜怎么做文章目录 内核启动后初始化程序简介BusyBox initBuildroot init 脚本 后记 内核启动后 内核引导代码在initramfs中通过内核命令行中的root指定的文件系统中去寻找根系统文件#xff0c;并执行一个相应的程序。在默认情况下#xff0c;对于initramfs这个程序是/init#xff0… 文章目录 内核启动后初始化程序简介BusyBox initBuildroot init 脚本 后记 内核启动后 内核引导代码在initramfs中通过内核命令行中的root指定的文件系统中去寻找根系统文件并执行一个相应的程序。在默认情况下对于initramfs这个程序是/init对于常规文件系统是/sbin/init程序。init程序具有root权限且因为它是第一个运行的进程所以其进程IDPID是1。如果init程序未能启动则内核将会崩溃。 init程序是所有其他进程的祖先。在这里通过pstree命令可以看出在大部分版本中init通常是psmisc包中的一部分
# pstree -gn init(1)--syslogd(63)|-klogd(66)|-dropbear(99)-sh(100)---pstree(109)init程序的任务是接管系统并使之运行。它和运行shell脚本的shell命令一样简单。
在启动阶段它启动守护进程配置系统参数以及负责让系统进入工作状态所需要做的配置操作。作为可选项它可以启动其他守护进程如在终端上的getty守护进程该进程允许登录shell。接收那些因为直接父进程被终止以及线程组中没有其他进程而形成的孤儿进程。它通过捕捉信号SIGCHLD并收集其返回值以防止它们成为僵尸进程对init的直接子进程的终止进行响应。作为一个可选项它重新启动那些已经终止的守护进程。它处理系统关机。 换句话说init管理着系统从开机到关机的整个生命周期。 初始化程序简介 在嵌入式设备中你最有可能遇到三个初始化程序是BusyBox init、System V init 和 systemd。Buildroot默认只构建BusyBox init你也可以选择构建所有三个初始化程序。Yocto项目默认构建System V init当然其他两种也可以选择。
类别Busy Box initSystem V initsystemd复杂性低中高启动速度快慢中所需shellashash 或 bash无可执行程序数量0450构建系统时的配置支持的C库任意任意glibc大小(MB)00.134构建系统时的配置 systemd的50个可执行程序、34MB的大小都是基于Buildroot的配置。 一般来说从BusyBox init到 systemd灵活性和复杂性都会逐渐增加。
BusyBox init BusyBox 的 init 程序最小它使用配置文件/etc/inittab来定义规则在系统启动阶段控制程序启动在关机阶段控制程序终止。通常情况下实际工作是由shell脚本来完成的而按照惯例脚本会放置在/etc/init.d目录下。 init 首先会读取配置文件/etc/inittab。配置文件包含了一个需要运行的程序列表一行一个格式如下
id::action:programid指令所针对的控制终端action运行该指令的条件将在下面的段落展示program待运行的程序 运行该指令的条件action字段的可填写的内容
sysinit在其他所有类型的操作之前当初始化开始时运行程序。respawn运行指定程序如果程序终止则重新启动。askfirst与respawn相同但是这个会向控制台输出“Please press Enter to activate this console”并在按下Enter键时运行该程序。它用于在终端上启动一个交互式shell且不提示输入用户名或密码。once运行指定程序如果该程序终止不会尝试重新启动它。wait运行指定程序并等待其完成。restart当init接收到信号SIGHUP时这表明其应该重新载入inittab文件此时运行指定程序。ctrlaltdel当init接收到信号SIGINT时运行指定程序这通常是由于用户在控制台按下了 CtrlAltDel 组合按键。shutdown当init关闭时运行指定程序。
这是一个完整的实际使用的inittab文件
# /etc/inittab
#
# Copyright (C) 2001 Erik Andersen andersencodepoet.org
#
# Note: BusyBox init doesnt 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 tty to run on, or empty for /dev/console
# runlevels ignored
# action one of sysinit, respawn, askfirst, wait, and once
# process program to run# Startup the system
::sysinit:/bin/mount -t proc proc /proc
::sysinit:/bin/mount -o remount,rw /
::sysinit:/bin/mkdir -p /dev/pts
::sysinit:/bin/mkdir -p /dev/shm
::sysinit:/bin/mount -a 2/dev/null
::sysinit:/bin/hostname -F /etc/hostname
# now run any rc scripts
::respawn:-/bin/sh
::sysinit:/etc/init.d/rcS# Put a getty on the serial port
#ttyFIQ0::respawn:/sbin/getty -L ttyFIQ0 0 vt100 # GENERIC_SERIAL# Stuff to do for the 3-finger salute
#::ctrlaltdel:/sbin/reboot# Stuff to do before rebooting
::shutdown:/etc/init.d/rcK
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r/etc/inittab文件中action字段的意义
action名称执行条件说明sysinit系统启动后最先执行只执行一次init进程等待它结束后才继续执行其他动作wait系统执行完sysinit进程后只执行一次init进程等待它结束才继续执行其他动作once系统执行完wait进程后只执行一次init进程不等待它结束respawn启动完once进程后init进程检测发现子进程退出时重新启动它askfirst启动完respawn进程后与respawn进程类型不过init进程先输出“Please press Enter to activate this console”等用户输入回车键之后才启动子进程。shutdown当系统关机时执行即重启、关闭系统命令时restartBusyBox中配置了CONFIG_FEATURE_USE_INITTAB并且init进程接收到SIGHUP信号时先重新读取、解析/etc/inittab文件再执行restart程序ctrlaltdel按下 CtrlAltDel 组合键时
以下是一个小例子包括挂载的 proc 和 sysfs 以及在串行接口运行 shell
null::sysinit:/bin/mount -t proc proc /proc
null::sysinit:/bin/mount -t sysfs sysfs /sys
console::askfirst:-/bin/sh对于简单的项目比如你只想启动少量的守护进程或者是在串口终端启动一个登录shell手写一个脚本也很容易。这种情况下如果你创建一个简单的定制的嵌入式Linux是很合适的。然而你会发现随着需要配置的事情不断增加手写一个init脚本很快就会变得非常难以维护。
Buildroot init 脚本 多年以来Buildroot有效使用了BusyBox 的init程序。Buildroot在/etc/init.d目录中有两个脚本名为 rcS 和 rcK 。第一个脚本 rcS 在开机时运行并从一个大写S加两位数字开始遍历所有的脚步并按数字顺序运行这就是开始脚本。rcK 脚本在关机时运行从一个大写K 加两位数字开始遍历所有的脚本并按数字顺序运行这就是结束脚本。 以上的做法也是存在的实际上更多做法是在目录/etc/init.d里面只有众多的S开头的启动脚本在S开头的脚本里面通过传入的参数start或者stop来执行开机时的操作逻辑或者关机时的操作逻辑。
一个典型实际使用的rcS脚本
#!/bin/sh# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do# Ignore dangling symlinks (if any).[ ! -f $i ] continuecase $i in*.sh)# Source shell script for speed.(trap - INT QUIT TSTPset start. $i);;*)# No sh extension, so fork subprocess.$i start;;esac
done一个典型实际使用的rcK脚本
#!/bin/sh# Stop all init scripts in /etc/init.d
# executing them in reversed numerical order.
#
for i in $(ls -r /etc/init.d/S??*) ;do# Ignore dangling symlinks (if any).[ ! -f $i ] continuecase $i in*.sh)# Source shell script for speed.(trap - INT QUIT TSTPset stop. $i);;*)# No sh extension, so fork subprocess.$i stop;;esac
done一个典型实际使用的S开头的用于alsa系统启动的脚本 S04alsa.sh
#!/bin/sh
#case $1 instart)if [ -f /etc/asound.state ];thenalsactl restore -f /etc/asound.statefi#enable spkecho 1 /proc/rp_power/spk_onecho 0 /proc/rp_power/spk_mute;;stop)echo not stop function;;*)echo Usage: $0 {start|stop}exit 1;;
esac在操作系统中一般系统的服务都是以后台进程的方式存在而且都会常驻系统中直到关机才结束。这类服务也称Daemon在Linux系统中就包含许多的Daemon。判断Daemon最简单的方法就是从名称上看。多数的Daemon都是由服务名称加上d。例如在Linux操作系统中HTTP服务的Deamon就是httpd。 通过这一套机制Buildroot包能够很容易地提供自己的开始脚本和结束脚本并利用两个数字编号影响这些脚本的运行顺序使其按照应有的顺序执行从而使系统成为可扩展的。
后记
其他的init程序比如System V init 和 systemd笔者也没有使用过有兴趣可以去看《嵌入式Linux编程》【Chris Simmonds】这本书的【第9章 启动初始化程序】的9.4和9.5小节。