我不认为kthreadd 开始init(在你的情况下符号链接到systemd)。
init 由内核初始化启动。 kthreadd 紧随其后。请参阅此 kernel threads wikipage,对于 Linux 4.2,其文件 init/main.c,函数 rest_init,靠近第 397 行,您可以在其中看到:
/*
* We need to spawn init first so that it obtains pid 1, however
* the init task will end up wanting to create kthreads, which, if
* we schedule it before we create kthreadd, will OOPS.
*/
kernel_thread(kernel_init, NULL, CLONE_FS);
numa_default_policy();
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
所以kthreadd不开始init,但两者都在被调度之前在内核中启动,所以在开始执行之前。
静态 kernel_init 函数(init/main.c 的第 930 - 975 行)具有显着的:
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;
因此正在设置 init 进程(à la execve(2)....)并已硬连线 /sbin/init 等...
init process 的 pid 为 1 很长时间了(从 1970 年代的原始 Unix 开始,在没有内核线程的旧 Linux 1.x 内核中也是如此)。这是一个强大的 Unix 约定(可能很多软件都依赖于它)。您可以使用systemd 作为您的init 进程,但您也可以使用sysvinit 或简单地使用bash(有时通过GRUB 将init=/bin/bash 传递给内核以进行修复很有用目的)或其他东西(例如runit)