Linux内核执行start_kernel函数时会调用kernel_init来启动init进程,流程如下图:
graph LR A[start_kernel] -->B(rest_init) B --> C(kernel_init) C --> D[try_to_run_init_process]
kernel_init部分代码如下:
994 if (execute_command) {
995 ret = run_init_process(execute_command);
996 if (!ret)
997 return 0;
998 panic("Requested init %s failed (error %d).",
999 execute_command, ret);
1000 }
1001 if (!try_to_run_init_process("/sbin/init") ||
1002 !try_to_run_init_process("/etc/init") ||
1003 !try_to_run_init_process("/bin/init") ||
1004 !try_to_run_init_process("/bin/sh"))
1005 return 0;
1006
1007 panic("No working init found. Try passing init= option to kernel. "
1008 "See Linux Documentation/init.txt for guidance.");
接着分析openwrt中package/system/procd/Makefile,这里将procd源码编译生成的可执行文件安装到文件系统的*/sbin*目录中。
define Package/procd/install
$(INSTALL_DIR) $(1)/sbin $(1)/etc $(1)/lib/functions
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{init,procd,askfirst,udevtrigger} $(1)/sbin/
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libsetlbf.so $(1)/lib
$(INSTALL_BIN) ./files/reload_config $(1)/sbin/
$(INSTALL_DATA) ./files/hotplug*.json $(1)/etc/
$(INSTALL_DATA) ./files/procd.sh $(1)/lib/functions/
endef
查看procd源码目录的CMakeList.txt,以init为例,对应源码编译文件如下
56 IF(DISABLE_INIT)
57 ADD_DEFINITIONS(-DDISABLE_INIT)
58 ELSE()
59 ADD_EXECUTABLE(init initd/init.c initd/early.c initd/preinit.c initd/mkdev.c watchdog.c
60 utils/utils.c ${SOURCES_ZRAM})
61 TARGET_LINK_LIBRARIES(init ${LIBS})
62 INSTALL(TARGETS init
63 RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
64 )
65
66 ADD_EXECUTABLE(udevtrigger plug/udevtrigger.c)
67 INSTALL(TARGETS udevtrigger
68 RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
69 )
70 ENDIF()
main函数入口位于initd/init.c
int
main(int argc, char **argv)
{
pid_t pid;
ulog_open(ULOG_KMSG, LOG_DAEMON, "init");
sigaction(SIGTERM, &sa_shutdown, NULL);
sigaction(S

本文详细分析了OpenWRT系统中procd的启动流程,从kernel_init开始,到procd的main函数、uloop_init、preinit的执行,以及如何处理hotplug事件和内核uevent。procd通过fork子进程执行/etc/preinit脚本,调用hook函数,并进入状态机处理,如STATE_EARLY、STATE_UBUS和STATE_INIT等。在STATE_INIT阶段,procd执行inittab中的回调函数,处理rcS.c和/etc/rc.d下的脚本。

4628

被折叠的 条评论
为什么被折叠?



