前提:
linux内核启动运行到run_init_process("sbin/init")
为什么入口是init_main?
执行/sbin/init进程的时候,会执行lbbmain()或者main(),这两个是根据宏定义来命名的。调用run_applet_no_and_exit从函数数组applet_main中查找init_main来调用,相应的,如果是别的指令比如说ls就调用ls_main
另外init本身也可以调用lbbmain()或者main()来执行新的进程(作业)
init_main:
首先初始化全局变量和信号掩码
(如果定义了调试模式,就初始化调试处理器)
检查PID是否为1
设置die_fun为sleep_much(这个函数是睡眠30天)
初始化控制台和设置环境变量
打印欢迎信息
检查是否为单用户模式,分情况调用new_init_action
不是单用户模式时通过parse_inittab调用多个new-init_action
#if ENABLE_SELINUX
{ 加载SELinux策略
... }
#if ENABLE_FEATURE_INIT_MODIFY_CMDLINE
修改命令行,让ps仅显示init不显示其他初始化进程
设置SIGSTOP和SIGTSTP信号处理函数
执行初始化命令:调用多个run_actions()
循环执行动作
while(1){
重新运行respawn/askfirst命令
等待任何信号(通常是SIGCHLD)
等待任何子进程退出
sleep(1);
//初始化完成后init就留在这个死循环里面,init不会终止,当产生孤儿进程时,init会作为孤儿进程的父进程。
}
parse_inittab:
打开inittab,进行相应配置(etc文件夹里全是配置文件)
/etc/inittab 主要用于系统启动时定义各种初始化任务、控制台设置、重启行为等。在 inittab 文件中,每一行定义了一个任务或操作。
从输出信息可以看到调用了5个new_init_action
run_actions:
根据不同的状态分情况调用run函数,其中有(SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN)这三种状态任意个的需要显式等待子进程的完成
run:
shell里每个创建的进程都是一个新的作业,需要重设信号集和进程组。
open_stdio_to_tty:
这个函数就是把标准输入输出重定位到新建的进程
显然,只有新的进程是一个终端时,才能样做
这个函数通过判断tty_name是否为空决定是否重定位,不空就重定位
一些注意
设置die_func为sleep_much的目的
防止init进程退出: init进程是系统中的第一个进程(PID 1),负责系统的初始化和管理所有其他进程。如果init进程退出,系统将会进入一种不可恢复的状态,通常会导致系统崩溃。因此,防止init进程退出是至关重要的。
防止内核恐慌: 如果init进程退出,系统可能会发生内核恐慌(kernel panic),这是内核检测到不可恢复的错误时采取的保护机制。通过让init进程进入长时间的休眠,可以避免内核恐慌的发生。
给予管理员时间进行干预: 长时间的休眠提供了一个缓冲期,允许系统管理员在检测到问题后有时间进行干预和修复,而不是立即面对系统崩溃。
系统恢复的最后手段: 在某些情况下,即使init进程遇到了致命错误,它仍然可以通过进入休眠状态来保持系统的基本稳定性,这样即使不能立即解决问题,系统也不会立即崩溃。
用户进程和内核线程
· 用户进程是在用户空间中运行的独立实体,具有自己的虚拟地址空间和资源,主要用于用户应用程序的执行。
· 内核线程是在内核空间中运行的线程,用于处理系统级任务,它们共享内核地址空间和资源,通常用于支持内核的操作和任务
输出信息
VFS: Mounted root (ext3 filesystem) readonly on device 179:0.
Freeing unused kernel memory: 1024K
lsj -- run_init_process is called. init_filename:/sbin/init
Run /sbin/init as init process
lsj -- kernel_execve is called. filename is : /sbin/init
random: crng init done
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is /sbin/init
lsj -- parse_init is called.
lsj -- new_init_action is called. command is /etc/init.d/rcS tty is
lsj -- new_init_action is called. command is -/bin/sh tty is /dev/console
lsj -- new_init_action is called. command is /sbin/reboot tty is
lsj -- new_init_action is called. command is /bin/umount -a -r tty is
lsj -- new_init_action is called. command is /sbin/init tty is
| lsj -- init_main calls run_actions(SYSINIT)
||| lsj -- run is called.
||| lsj -- open_stdio_to_tty is called. tty_name is
||| lsj -- wait for pid: []
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is /bin/sh
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is mount
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is mkdir
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is mount
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is mdev
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is mkdir
mkdir: can't create directory '/var/lock': Read-only file system
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is ifconfig
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is /bin/hostname
| lsj -- init_main calls run_actions(WAIT)
| lsj -- init_main calls run_actions(ONCE)
| lsj -- in while(1): init_main calls run_actions(ONCE)
||| lsj -- run is called.
||| lsj -- open_stdio_to_tty is called. tty_name is /dev/console
Please press Enter to activate this console.
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is -/bin/sh
[root@lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is /bin/hostname
vexpress ]# ls
lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is ls
bin lib mnt sbin usr
dev linuxrc proc sys var
etc lost+found root tmp
[root@lsj -- lbb_main or main is called.
lsj -- run_applet_no_and_exit is called. argv[0] is /bin/hostname
vexpress ]#