start_kernel函数的最后调用rest_init函数来创建并启动内核线程
1 static noinline void __init_refok rest_init(void) 2 { 3 int pid; 4 5 rcu_scheduler_starting(); 6 /* 7 * We need to spawn init first so that it obtains pid 1, however 8 * the init task will end up wanting to create kthreads, which, if 9 * we schedule it before we create kthreadd, will OOPS. 10 */ 11 kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); 12 numa_default_policy(); 13 pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); 14 rcu_read_lock(); 15 kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); 16 rcu_read_unlock(); 17 complete(&kthreadd_done); 18 19 /* 20 * The boot idle thread must execute schedule() 21 * at least once to get things moving: 22 */ 23 init_idle_bootup_task(current); 24 preempt_enable_no_resched(); 25 schedule(); 26 preempt_disable(); 27 28 /* Call into cpu_idle with preempt disabled */ 29 cpu_idle(); 30 }
存档