JJJ:linux系统中第一个进程

以linux4.19内核linux系统中第一个进程。

执行shell指令 ps -ef 结果如下:

xxx@xxx-virtual-machine:~$ ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 20:55 ?        00:00:02 /sbin/init splash
root           2       0  0 20:55 ?        00:00:00 [kthreadd]
root           3       2  0 20:55 ?        00:00:00 [rcu_gp]
root           4       2  0 20:55 ?        00:00:00 [rcu_par_gp]
root           5       2  0 20:55 ?        00:00:00 [slub_flushwq]
root           6       2  0 20:55 ?        00:00:00 [netns]
root           8       2  0 20:55 ?        00:00:00 [kworker/0:0H-events_highpri]
root          10       2  0 20:55 ?        00:00:00 [mm_percpu_wq]
root          11       2  0 20:55 ?        00:00:00 [rcu_tasks_rude_]
root          12       2  0 20:55 ?        00:00:00 [rcu_tasks_trace]
root          13       2  0 20:55 ?        00:00:00 [ksoftirqd/0]
root          14       2  0 20:55 ?        00:00:00 [rcu_sched]
root          15       2  0 20:55 ?        00:00:00 [migration/0]
root          16       2  0 20:55 ?        00:00:00 [idle_inject/0]
root          17       2  0 20:55 ?        00:00:00 [kworker/0:1-events]
root          18       2  0 20:55 ?        00:00:00 [cpuhp/0]
root          19       2  0 20:55 ?        00:00:00 [cpuhp/1]
root          20       2  0 20:55 ?        00:00:00 [idle_inject/1]
root          21       2  0 20:55 ?        00:00:00 [migration/1]
...

可以看到第一个进程PID为1,拉起第一个进程的指令为/sbin/init splash

内核启动流程:
start_kernel (init/main.c)
kernel_init

kernel_init函数如下:

static int __ref kernel_init(void *unused)
{
	...
	if (ramdisk_execute_command) {
		ret = run_init_process(ramdisk_execute_command);
		if (!ret)
            return 0;
        pr_err("Failed to execute %s (error %d)\n", ramdisk_execute_command, ret);
    }

    /*
     * We try each of these until one succeeds.
     *
     * The Bourne shell can be used instead of init if we are
     * trying to recover a really broken machine.
     */
    if (execute_command) {
        ret = run_init_process(execute_command);
        if (!ret)
            return 0;
        panic("Requested init %s failed (error %d).",
              execute_command, ret);
    }
    if (!try_to_run_init_process("/sbin/init") ||
        !try_to_run_init_process("/etc/init") ||
        !try_to_run_init_process("/bin/init") ||
        !try_to_run_init_process("/bin/sh"))
        return 0;

    panic("No working init found.  Try passing init= option to kernel. "
          "See Linux Documentation/admin-guide/init.rst for guidance.");

}

上面代码片中的两个变量:ramdisk_execute_command 和 execute_command。
其定义如下:

static int __init init_setup(char *str)
{
    unsigned int i;

    execute_command = str;
    /*
     * In case LILO is going to boot us with default command line,
     * it prepends "auto" before the whole cmdline which makes
     * the shell think it should execute a script with such name.
     * So we ignore all arguments entered _before_ init=... [MJ]
     */
    for (i = 1; i < MAX_INIT_ARGS; i++)
        argv_init[i] = NULL;
    return 1;
}
__setup("init=", init_setup);

static int __init rdinit_setup(char *str)
{
    unsigned int i;

    ramdisk_execute_command = str;
    /* See "auto" comment in init_setup */
    for (i = 1; i < MAX_INIT_ARGS; i++)
        argv_init[i] = NULL;
    return 1;
}
__setup("rdinit=", rdinit_setup);

使用__setup("init=", init_setup)宏注册了这个函数,这样当内核启动时遇到
init=<command>这样的启动参数时,就会调用init_setup函数进行处理。
  • ramdisk_execute_command
    ramdisk_execute_command 变量的值可以通过内核启动参数 rdinit 来设置。在Linux内核引导过程中,如果用户在命令行参数或GRUB等 bootloader配置中指定了类似 rdinit=/path/to/executable 的参数,内核在初始化initrd之后会尝试执行位于指定路径的可执行文件作为初始化脚本或进程。

  • execute_command
    类似上面

在这里插入图片描述

相关推荐

  1. Linux第一小程序---进度

    2024-04-01 07:04:03       38 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-01 07:04:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-01 07:04:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-01 07:04:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-01 07:04:03       18 阅读

热门阅读

  1. 【Git】分支协同开发

    2024-04-01 07:04:03       12 阅读
  2. Oracle分区默认segment大小变化(64k—>8M)

    2024-04-01 07:04:03       11 阅读
  3. 如何系统地自学Python?

    2024-04-01 07:04:03       16 阅读
  4. C++ & MFC

    C++ & MFC

    2024-04-01 07:04:03      11 阅读
  5. Android SQLite的使用

    2024-04-01 07:04:03       14 阅读
  6. Docker + Nginx 安装

    2024-04-01 07:04:03       16 阅读
  7. get和post的区别!

    2024-04-01 07:04:03       17 阅读
  8. 01-XML-02XML DTD定义文档结构

    2024-04-01 07:04:03       15 阅读