zz內核初始化

https://www.cnblogs.com/JaPer/p/10781136.htmlhtml


 

內核啓動的入口函數  start_kernel()   {init/main.c配置文件} , 裏面有XXXX_init的初始化函數安全

 

 

 

1)在操做系統中有個創始進程,set_task_stack_end_magic(&init_task)。 有一個參數 init_task 定義是struct task_struct init_task = INIT_TASK(init_task)  是系統默認建立的第一進程(0號進程) 惟一一個沒有經過fork或者Kernel_thread 產生的進程數據結構

(Procese List) 項目管理進程 , 內有全部項目多線程

2)辦事大廳:  函數(trap_init())  其中設置了不少中斷門(Interrupt Gate)函數

其中 set_system_intr_gate(IA32_SYSCALL_VECTOR,entry_INT80_32)  爲系統調用的中斷門。 而且經過發送中斷的方式進行的。 (64位有另外的系統調用方法)操作系統

3) 會議室管理系統: 初始化內存管理模塊【mm_init()】 線程

           初始化調度模塊【 sched_init()】    進行調度時則須要執行必定的調度策略翻譯

   文件系統 rootfs   初始化基於內存的文件系統【 vfs_caches_init()】 rest

             函數裏調用 mnt_init()-> init_rootfs() orm

              register_filesystem(&rootfs_fs_type) ,在VFS 虛擬文件系統裏註冊了一種類型  定義爲 struct file_system_type rootfs_fs_type 

    文件系統即爲項目資料庫。首先要兼容全部的文件系統,需將文件的相關數據結構和操做抽象出來,造成一個對上提供統一的接口。這個抽象層就是VFS ( Virtual File System) 。虛擬文件系統

  此時,rootfs 還有其餘用處。 

   start_kernel() 調用的是 rest_init() 。 是作其餘方面的初始化

           

4) rest_init 爲原始進程 要建立第二個進程則用 kernel_thread(kernel_init,NULL,CLONE_FS) 

  當進程出現的時候就要考慮安全性,並將進程作一些主要的權限區分等級,好比哪些是核心資源,那些事非核心資源。

 核心關鍵資源放在內部,則稱爲內核態(Kernel Mode)

 普通的程序資源則可放在應用裏,則稱爲用戶態(User Mode)

系統啓動時已經處於保護模式。則用戶的權限直接致使當前用戶的訪問空間以及讀寫等操做空間。

若普通用戶想訪問核心資源,則須要提供系統調用的辦事大廳,可在此請求。而後就是內核態, 等用戶態代碼作完了返回結果就能夠了。

若用戶態的程序運行一半的時候須要訪問內核資源,則暫停當前運行,調用系統調用,而後轉到內核中的代碼繼續運行。而後再內核網卡上進行排隊處理。等處理完成後也就是系統調用結束,則返回到用戶態,繼續暫停的程序

程序過程: 用戶態 — 系統調用 — 保持寄存器 — 內核態執行系統調用 — 恢復寄存器 — 返回用戶態,而後接着運行。

5) 從內核態到用戶態

當執行 kernel_thread 函數時,咱們處於內核態,kernel_thread 的參數是一個函數 kernel_init 而且會此進程會運行此函數, 在此裏面會調用 kernel_init_freeable() :

            if (!ramdisk_execute_command)

            ramdisk_execute_command = "/init";

 進程運行的是一個文件,若打開run_init_process函數。則發現它調用的是 do_execve 。 (execve 是系統調用,做用是運行一個執行文件,加一個do_ 則是內核系統調用的實現。  而且會嘗試運行 ramdisk 的 「/init「 或者 」/sbin/init" , "/etc/init"  , "/bin/init" , "/bin/sh"  。 不一樣的Linux版本會選擇不一樣的文件啓動,但只須要有一個啓動便可。

則調用過程 do_execve -> do_execveat_common -> exec_binprm -> search_binary_handler, 

運行加載二進制文件,則須要Linux下經常使用的格式 ELF ( Executable and Linkable Format,可執行與可連接格式)

6) Ramdisk 的做用

當訪問一個U盤或存儲系統的時候,則須要安裝驅動才能訪問,若存儲系統過多,則安裝的驅動也多。此時則先弄一個基於內存的文件系統,內存訪問則不須要驅動。這個就叫 ramdisk。 ramdisk 則是根文件系統 

而後運行 ramdisk 上的 /init 。運行完了就已經在用戶態上了。 /init 程序會先根據存儲系統的類型加載驅動,而後設置真正的根文件系統, 而後ramdisk上的 /init 會啓動文件系統上的 init,而後就是各類系統初始化,啓動系統的服務,啓動控制檯,用戶登錄等等。。。

7) 建立 2號進程

Kernel_thread(kthreadd,NULL,ClONE_FS | CLONE_FILES)  使用kernel_thread 函數建立進程 【函數名 thread 可翻譯爲 「線程」 】

從用戶態來看,建立進程即爲立項,也就是啓動項目,此項目包含會議室,資料庫等。 但項目須要人去執行,如有多我的並行執行不一樣的部分,則稱爲多線程 (Multithreading),若只有一我的,那則是此項目的主線程。

從內核看,不管進程仍是線程,統稱爲任務(Task),使用相同的數據結構,平放在同一個鏈表中。 

於此,函數 kthreadd 負責全部內核態的線程的調度和管理,是內核態全部線程運行的祖先