内核空间启动主要流程:
1、init/main.c start_kernel()
2、init/main.c rest_init()
3、init/main.c kernel_init()
4、init/main.c init_post()
内核至用户空间启动主要流程:
1、如果bootloader设置了启动参数,则将"rdinit = "参数赋予ramdisk_execute_command,将"init = "参数赋予execute_command。
2、如果ramdisk_execute_command==NULL,且/init文件可访问,则令ramdisk_execute_command="/init"。
3、如果ramdisk_execute_command!=NULL,则执行run_init_process(ramdisk_execute_command)。
4、如果execute_command!=NULL,则执行run_init_process(execute_command)。
5、执行run_init_process("/sbin/init");
6、执行run_init_process("/etc/init");
7、执行run_init_process("/bin/init");
8、执行run_init_process("/bin/sh");
9、进行panic提示:panic("No init found. Try passing init= option to kernel.");
备注:
run_init_process会调用kernel_execve,kernel_execve会执行系统调用将系统由内核空间切换到用户空间。kernel_execve执行成功后不会返回。
Openwrt用户空间启动主要流程:
1、/etc/preinit
# linux内核启动后,首先运行/etc/preinit脚本,preinit脚本是一系列脚本的入口。在配置文件中可以看到“init=/etc/preinit”。
2、/sbin/init
# 在/etc/preinit文件中被指定。/sbin/init -> ../bin/busybox。
3、/etc/inittab
# busybox的init命令执行/etc/inittab的脚本。
4、/etc/init.d/rcS
# 根据/etc/inittab,系统启动时会执行/etc/init.d/rcS S boot脚本。
5、/etc/rc.d/S*
# /etc/init.d/rcS S boot脚本将运行/etc/rc.d目录下S开头的的所有脚本。