Buildroot(2022.08-rc1)+busybox(1.35.0)启动流程

发布时间 2023-04-27 19:41:58作者: ArnoldLu

 关键词:busybox,inittab,syslogd,klogd,mdev,modprobe,watchdog,telnetd等等。

 

busybox启动流程简单解析:从init到shell login》详细介绍了init对inittab的解析和执行。

下面为buildroot(2022.08-rc1)的启动脚本:

/etc/inittab
    sysinit
        ->/bin/mount -t proc proc /proc
        ->/bin/mount -o remount,rw /
        ->/bin/mkdir -p /dev/pts /dev/shm
        ->/bin/mount -a
        ->/bin/mkdir -p /run/lock/subsys
        ->/sbin/swapon -a
        ->/bin/ln -sf /proc/self/fd /dev/fd
        ->/bin/ln -sf /proc/self/fd/0 /dev/stdin
        ->/bin/ln -sf /proc/self/fd/1 /dev/stdout
        ->/bin/ln -sf /proc/self/fd/2 /dev/stderr
        ->/bin/hostname -F /etc/hostname
        ->/etc/init.d/rcS
            ->S01syslogd
            ->S02klogd
            ->S10mdev
            ->S15watchdog
            ->S50telnet
    respawn
        ->/sbin/getty -L console 0 vt100
    shutdown
        ->/etc/init.d/rcK
        ->/sbin/swapoff -a
        ->/bin/umount -a -r

start-stop-daemon

start-stop-daemon启动或停止守护进程。

Usage: start-stop-daemon [OPTIONS] [-S|-K] ... [-- ARGS...]

Search for matching processes, and then
-K: stop all matching processes
-S: start a process unless a matching process is found

Process matching:
    -u USERNAME|UID    Match only this user's processes
    -n NAME        Match processes with NAME
            in comm field in /proc/PID/stat
    -x EXECUTABLE    Match processes with this command
            in /proc/PID/cmdline
    -p FILE        Match a process with PID from FILE
    All specified conditions must match
-S only:
    -x EXECUTABLE    Program to run
    -a NAME        Zeroth argument
    -b        Background
    -N N        Change nice level
    -c USER[:[GRP]]    Change user/group
    -m        Write PID to pidfile specified by -p
-K only:
    -s SIG        Signal to send
    -t        Match only, exit with 0 if found
Other:
    -o        Exit with status 0 if nothing is done
    -v        Verbose
    -q        Quiet

S01syslogd

S01syslogd启动syslogd服务,执行"syslogd -n"。将pid写入文件中,后面可以通过start-stop-daemon关闭。

syslog用来记录应用程序或者硬件设备的日志;通过syslogd这个进程记录系统有关事件记录,也可以记录应用程序运作事件。

syslogd日志记录器由两个守护进程(klogd,syslogd)和一个配置文件(syslog.conf)组成。

详细参见《Busybox的syslogd认识与使用》。

#!/bin/sh

DAEMON="syslogd"
PIDFILE="/var/run/$DAEMON.pid"

SYSLOGD_ARGS=""

# shellcheck source=/dev/null
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"

# BusyBox' syslogd does not create a pidfile, so pass "-n" in the command line
# and use "-m" to instruct start-stop-daemon to create one.

start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/sbin/$DAEMON"-- -n $SYSLOGD_ARGS

start-stop-daemon -K -q -p "$PIDFILE"

S02klogd

klogd首先接收内核的日志,然后将之发送给syslogd。

#!/bin/sh

DAEMON="klogd"
PIDFILE="/var/run/$DAEMON.pid"

KLOGD_ARGS=""

# shellcheck source=/dev/null
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"
start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/sbin/$DAEMON" -- -n $KLOGD_ARGS start-stop-daemon -K -q -p "$PIDFILE"

S02sysctl

#!/bin/sh
#
# This script is used by busybox and procps-ng.
#
# With procps-ng, the "--system" option of sysctl also enables "--ignore", so
# errors are not reported via syslog. Use the run_logger function to mimic the
# --system behavior, still reporting errors via syslog. Users not interested
# on error reports can add "-e" to SYSCTL_ARGS.
#
# busybox does not have a "--system" option neither reports errors via syslog,
# so the scripting provides a consistent behavior between the implementations.
# Testing the busybox sysctl exit code is fruitless, as at the moment, since
# its exit status is zero even if errors happen. Hopefully this will be fixed
# in a future busybox version.

PROGRAM="sysctl"

SYSCTL_ARGS=""

# shellcheck source=/dev/null
[ -r "/etc/default/$PROGRAM" ] && . "/etc/default/$PROGRAM"

# Files are read from directories in the SYSCTL_SOURCES list, in the given
# order. A file may be used more than once, since there can be multiple
# symlinks to it. No attempt is made to prevent this.
SYSCTL_SOURCES="/etc/sysctl.d/ /usr/local/lib/sysctl.d/ /usr/lib/sysctl.d/ /lib/sysctl.d/ /etc/sysctl.conf"

# If the logger utility is available all messages are sent to syslog, except
# for the final status. The file redirections do the following:
#
# - stdout is redirected to syslog with facility.level "kern.info"
# - stderr is redirected to syslog with facility.level "kern.err"
# - file dscriptor 4 is used to pass the result to the "start" function.
#
run_logger() {
    # shellcheck disable=SC2086 # we need the word splitting
    find $SYSCTL_SOURCES -maxdepth 1 -name '*.conf' -print0 2> /dev/null | \
    xargs -0 -r -n 1 readlink -f | {
        prog_status="OK"
        while :; do
            read -r file || {
                echo "$prog_status" >&4
                break
            }
            echo "* Applying $file ..."
            /sbin/sysctl -p "$file" $SYSCTL_ARGS || prog_status="FAIL"
        done 2>&1 >&3 | /usr/bin/logger -t sysctl -p kern.err
    } 3>&1 | /usr/bin/logger -t sysctl -p kern.info
}

# If logger is not available all messages are sent to stdout/stderr.
run_std() {
    # shellcheck disable=SC2086 # we need the word splitting
    find $SYSCTL_SOURCES -maxdepth 1 -name '*.conf' -print0 2> /dev/null | \
    xargs -0 -r -n 1 readlink -f | {
        prog_status="OK"
        while :; do
            read -r file || {
                echo "$prog_status" >&4
                break
            }
            echo "* Applying $file ..."
            /sbin/sysctl -p "$file" $SYSCTL_ARGS || prog_status="FAIL"
        done
    }
}

if [ -x /usr/bin/logger ]; then
    run_program="run_logger"
else
    run_program="run_std"
fi

start() {
    printf '%s %s: ' "$1" "$PROGRAM"
    status=$("$run_program" 4>&1)
    echo "$status"
    if [ "$status" = "OK" ]; then
        return 0
    fi
    return 1
}

case "$1" in
    start)
        start "Running";;
    restart|reload)
        start "Rerunning";;
    stop)
        :;;
    *)
        echo "Usage: $0 {start|stop|restart|reload}"
        exit 1
esac

S10mdev

mdev配置文件为/etc/mdev.conf,遍历/sys/dev下面的block和char文件夹,创建/dev目录下设备节点。

DAEMON="mdev"
PIDFILE="/var/run/$DAEMON.pid"
start-stop-daemon -S -b -m -p $PIDFILE -x /sbin/mdev -- -df
start-stop-daemon -K -p $PIDFILE

 mdev详细参考《Linux uevent分析、用户接收uevent以及mdev分析》。

 modprobe将搜索到的module插入内核。

# coldplug modules
find /sys/ -name modalias -print0 | xargs -0 sort -u | tr '\n' '\0' | xargs -0 modprobe -abq

S15watchdog

启动watchdog设备,PERIOD为超时重启时间。。

watchdog -t PERIOD /dev/watchdog

S50telnet

#!/bin/sh
#
# Start telnet....
#

TELNETD_ARGS=-F
[ -r /etc/default/telnet ] && . /etc/default/telnet

start-stop-daemon -S -q -m -b -p /var/run/telnetd.pid -x /usr/sbin/telnetd -- $TELNETD_ARGS
start-stop-daemon -K -q -p /var/run/telnetd.pid -x /usr/sbin/telnetd