裝置驅動程式與核心模組

可載入核心模組(loadable kernel module)

核心是一支正在執行的單一程式,而通常你無法把程式碼加進一支正在執行的程式裡。但若把每一種可能的驅動程式都編進一個龐大的核心,不管你有沒有那個硬體都得開機帶著它,那太浪費了。可載入核心模組是一段分開編譯的核心程式碼,可按需插入正在執行的核心,之後再移除——就像在不關機的情況下替一台運轉中的機器加上新工具。

模組被建構成一個 .ko 檔(kernel object),那是一個 ELF 目的檔,內含程式碼以及一張描述其進入點的小表。當你執行 insmod 或 modprobe 時,核心載入器把模組的程式碼與資料複製進核心定址空間,解析它對核心所匯出符號的參考(這是動態連結,只是發生在核心內部),然後呼叫模組的 init 函式。從那一刻起,模組的程式碼就只是核心的一部分——它以核心模式執行、共用同一個核心定址空間,並能直接呼叫匯出的核心函式。rmmod 會呼叫模組的 exit 函式並把它卸載。

模組之所以重要,是因為它讓核心變得模組化:發行版只裝一個小核心,僅在需要時才載入驅動程式、檔案系統與協定,而開發者也能在不重開機的情況下反覆修改驅動程式。危險正是這份威力的反面:模組沒有被沙箱隔離。它以完整特權在核心的定址空間中執行,所以模組裡一個失控的指標就能塗寫到無關的核心記憶體。模組與核心其餘部分之間沒有保護邊界,這正是為什麼單一一個有臭蟲的模組就能讓整台機器恐慌(panic)。

$ sudo insmod hello.ko # 載入它 $ lsmod | grep hello # 確認已載入 $ dmesg | tail # 看它的 init 訊息 $ sudo rmmod hello # 卸載它 # modprobe 還會自動拉入相依模組

從 shell 看模組的一生:插入、檢視、移除。modprobe 會解析相依關係;insmod 不會。

模組不是行程,也沒有自己的受保護記憶體。因為它以完整特權共用核心定址空間,一個在應用程式裡只會無害地導致區段錯誤的臭蟲,可能讓整個核心當掉。

又称
LKMkernel module核心模組.ko file