1. 程式人生 > >Linux核心初始化步驟(三)

Linux核心初始化步驟(三)

在start_kernl函式的最後呼叫了reset_init函式進行後續的初始化


static noinline void __init_refok rest_init(void)
{
	int pid;

	rcu_scheduler_starting();//核心RCU鎖機制排程啟動
	/*
	 * 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.
	 */
	 /*我們必須先建立init程序以便於使它獲得程序號1,然而init程序將會被掛起來等待建立kthreads
	 執行緒,如果我們在建立kthreadd執行緒前排程它,將會導致OOPS錯誤*/
	 /*rest_init()函式最主要的歷史使命就是啟動核心執行緒kernel_init*/
	kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
	numa_default_policy();

	/*啟動核心執行緒kthreadd,執行kthread_create_list全域性連結串列中的kthread
	1.它迴圈執行一個叫做kthreadd的函式,該函式的作用是執行ktheard_create_list全域性連結串列中
	維護的核心執行緒;
	2.呼叫kthread_create建立一個kthread,它會被加入到kthread_create_list連結串列中;
	3.被執行過的kthread會從kthread_create_list連結串列中刪除
	4.且kthreadd會不斷呼叫scheduler函式讓出CPU,此執行緒不可關閉
	上面兩個執行緒就是我們平時在Linux系統中用ps命令看到:
	*/
	pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
	rcu_read_lock();
	kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
	rcu_read_unlock();
	complete(&kthreadd_done);
	
	/*1.獲取kthreadd的執行緒資訊,獲取完成說明kthreaddd已經建立成功。並通過一個complete
	變數(kthreadd_done)來通知kernel_init執行緒*/
	/*
	 * The boot idle thread must execute schedule()
	 * at least once to get things moving:
	 */
	init_idle_bootup_task(current);
	preempt_enable_no_resched();
	schedule();

	/* Call into cpu_idle with preempt disabled */
	preempt_disable();
	cpu_idle();
}

在這裡插入圖片描述