一. Linux内核启动
上一篇文章简单了解了 Linux内核启动第二阶段,涉及的 start_kernel函数。start_kernel 函数最后调用了 rest_init 函数,接下来简单看一下 rest_init 函数。
本文续上一篇文章的学习,地址如下:
Linux内核启动流程-第二阶段start_kernel 函数_凌肖战的博客-CSDN博客
二. Linux内核启动流程第二阶段
1. rest_init 函数
 
 rest_init  
 函数定义在文件  
 init/main.c  
 中,函数内容如下:  
 
 
383 static noinline void __init_refok rest_init(void)
384 {
385 int pid;
386
387 rcu_scheduler_starting();
388 smpboot_thread_init();
389 /*
390 * We need to spawn init first so that it obtains pid 1, however
391 * the init task will end up wanting to create kthreads, which, 
392 * if we schedule it before we create kthreadd, will OOPS.
393 */
394 kernel_thread(kernel_init, NULL, CLONE_FS);
395 numa_default_policy();
396 pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
397 rcu_read_lock();
398 kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
399 rcu_read_unlock();
400 complete(&kthreadd_done);
401
402 /*
403 * The boot idle thread must execute schedule()
404 * at least once to get things moving:
405 */
406 init_idle_bootup_task(current);
407 schedule_preempt_disabled();
408 /* Call into cpu_idle with preempt disabled */
409 cpu_startup_entry(CPUHP_ONLINE);
410 } 
 
 
 第  
 387  
 行,调用函数  
 rcu_scheduler_starting 
 ,启动  
 RCU  
 锁调度器。 
 
 
 
 第  
 394  
 行,调用函数  
 kernel_thread  
 创建  
 kernel_init  
 进程,也就是大名鼎鼎的  
 init  
 内核进程。  
 
 
 init  
 进程的  
 PID  
 为  
 1 
 。 
 init  
 进程一开始是内核进程 
 ( 
 也就是运行在内核态 
 ) 
 ,后面  
 init  
 进程会在根  
 
 
 文件系统中查找名为“ 
 init 
 ”这个程序,这个“ 
 init 
 ”程序处于用户态,通过运行这个“ 
 init 
 ”程  
 
 
 序, 
 init  
 进程就会实现从内核态到用户态的转变。 
 
 
 
 第  
 396  
 行,调用函数  
 kernel_thread  
 创建  
 kthreadd  
 内核进程,此内核进程的  
 PID  
 为  
 2 
 。 
 kthreadd进程负责所有内核进程的调度和管理。  
 
 
 
 第  
 409  
 行,最后调用函数  
 cpu_startup_entry  
 来进入  
 idle  
 进程, 
 cpu_startup_entry  
 会调用cpu_idle_loop 
 , 
 cpu_idle_loop  
 是个  
 while  
 循环,也就是  
 idle  
 进程代码。 
 idle  
 进程的  
 PID  
 为  
 0 
 , 
 idle  
 
 
 进程叫做空闲进程。 
 
 
 idle  
 空闲进程  
 ,当  
 CPU  
 没有事情做的时候就在  
 idle  
 空闲进程里面“瞎逛游”,反正就是给  
 CPU  
 找点事做。当其他进程要工作的时候就会抢占  
 idle  
 进程,从而夺取  
 CPU  
 使用权。其实大 
 家应该可看到  
 idle  
 进程并没有使用  
 kernel_thread  
 或者  
 fork  
 函数来创建,因为它是有主进程演 
 变而来的。  
 
 
 
 
 
 开发板上电后,输入“ps -A” 命令 就可以打印出当前系统中的所有进程,其中就能看到 init 进程和 kthreadd 进程,如下图所示: 
 
 

 
 可以看出, 
 init  
 进程的  
 PID  
 为  
 1 
 , 
 kthreadd  
 进程的  
 PID  
 为  
 2 
 。之所以上图 
 中没有显示  
 PID  
 为  
 0  
 的  
 idle  
 进程,那是因为  
 idle  
 进程是内核进程。 
 
 
 
 
 
 
我们接下来重点看一下 init 进程,kernel_init 就是 init 进程的进程函数。
















![[WUSTCTF2020]颜值成绩查询 布尔注入二分法](https://img-blog.csdnimg.cn/0592b587c5eb42c2b81108986f6cb789.png)


