busybox之内核线程init

前提:

        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 ]#

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值