主要流程
跟其他linux系统一样,openwrt系统启动,首先是boot加载kernel,kernel最终调用/etc/preinit
开始整个启动流程.
preinit -> init -> inittab -> rcS -> /etc/rc.d/^S* (S开头的脚本)
各流程理解
- preinit流程
文件位置:openwrt项目路径\package\base-files\files\etc\preinit
源代码:
#!/bin/sh
# Copyright (C) 2006-2016 OpenWrt.org
# Copyright (C) 2010 Vertical Communications
# 检查是否定义了环境变量 $PREINIT,如果没有,则执行 /sbin/init,这是系统的初始化进程。
[ -z "$PREINIT" ] && exec /sbin/init
# 设置了环境变量 PATH,以便在后续的命令中可以正确地找到系统命令。
export PATH="%PATH%"
# 引入了一些库文件,包括 /lib/functions.sh、/lib/functions/preinit.sh 和 /lib/functions/system.sh。这些库文件包含了一些系统函数和工具,用于系统初始化和启动。
. /lib/functions.sh
. /lib/functions/preinit.sh
. /lib/functions/system.sh
#初始化了一些钩子(hook),例如 preinit_essential、preinit_main、failsafe、initramfs 和 preinit_mount_root。这些钩子在系统启动过程中会被调用,执行一些特定的操作。
boot_hook_init preinit_essential
boot_hook_init preinit_main
boot_hook_init failsafe
boot_hook_init initramfs
boot_hook_init preinit_mount_root
# 遍历了 /lib/preinit/ 目录下的所有文件,并执行了这些文件。这些文件通常包含了一些系统初始化的脚本。
for pi_source_file in /lib/preinit/*; do
. $pi_source_file
done
#运行了 preinit_essential 钩子,然后设置了一些变量,如 pi_mount_skip_next、pi_jffs2_mount_success 和 pi_failsafe_net_message。
boot_run_hook preinit_essential
pi_mount_skip_next=false
pi_jffs2_mount_success=false
pi_failsafe_net_message=false
# 一个函数调用,它在系统启动过程中执行了名为 preinit_main 的钩子(hook)。钩子是一种在特定阶段执行的功能,用于执行一些初始化操作或设置变量。
boot_run_hook preinit_main
-
init流程
openwrt系统路径:sbin/init
过程:init程序最终会演变成init进程,一直存在于系统. 这个过程中它会解析/etc/inittab
文件,并根据规则执行inittab中预定的操作. -
inittab
源文件:openwrt项目路径\package\base-files\files\etc\inittab
源码解析:
::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K shutdown
::askconsole:/usr/libexec/login.sh
#其中第一行:`::sysinit:/etc/init.d/rcS S boot`指定,在系统启动或者重启时才执行,
执行的程序是:/etc/init.d/rcS S boot,接下来就进入了`rcS`的执行过程
- rcS
源文件:openwrt项目路径\package\base-files\files\etc\init.d\rcS
源码:
#!/bin/sh
# Copyright (C) 2006 OpenWrt.org
#查找所有/etc/rc.d下所有S开头的脚本,依据优先级依次执行
run_scripts() {
for i in /etc/rc.d/$1*; do
[ -x $i ] && $i $2 2>&1
done | $LOGGER
}
system_config() {
config_get_bool foreground $1 foreground 0
}
LOGGER="cat"
[ -x /usr/bin/logger ] && LOGGER="logger -s -p 6 -t sysinit"
. /lib/functions.sh
config_load system
config_foreach system_config system
if [ "$1" = "S" -a "$foreground" != "1" ]; then
run_scripts "$1" "$2" &
else
run_scripts "$1" "$2"
fi
- /etc/rc.d/^S*
/etc/rc.d/^S*
执行每个脚本,执行完毕,系统也就启动完成了.
ps:理解openwrt的启动流程有利于后续定制openwrt系统。