清單 4. 編譯 LKM
結(jié)果會(huì)生成一個(gè) simple-lkm.ko 文件。這個(gè)新的命名約定可以幫助將這些內(nèi)核對(duì)象(LKM)與標(biāo)準(zhǔn)對(duì)象區(qū)分開(kāi)來(lái)?,F(xiàn)在可以加載或卸載這個(gè)模塊了,然后可以查看它的輸出。要加載這個(gè)模塊,請(qǐng) 使用 insmod 命令;反之,要卸載這個(gè)模塊,請(qǐng)使用 rmmod 命令。lsmod 可以顯示當(dāng)前加載的 LKM(參見(jiàn)清單 5)。 清單 5. 插入、檢查和刪除 LKM
注意,內(nèi)核的輸出進(jìn)到了內(nèi)核回環(huán)緩沖區(qū)中,而不是打印到 stdout 上,這是因?yàn)?stdout 是進(jìn)程特有的環(huán)境。要查看內(nèi)核回環(huán)緩沖區(qū)中的消息,可以使用 dmesg 工具(或者通過(guò) /proc 本身使用 cat /proc/kmsg 命令)。清單 6 給出了 dmesg 顯示的最后幾條消息。 清單 6. 查看來(lái)自 LKM 的內(nèi)核輸出
可以在內(nèi)核輸出中看到這個(gè)模塊的消息?,F(xiàn)在讓我們暫時(shí)離開(kāi)這個(gè)簡(jiǎn)單的例子,來(lái)看幾個(gè)可以用來(lái)開(kāi)發(fā)有用 LKM 的內(nèi)核 API。 集成到 /proc 文件系統(tǒng)中 內(nèi)核程序員可以使用的標(biāo)準(zhǔn) API,LKM 程序員也可以使用。LKM 甚至可以導(dǎo)出內(nèi)核使用的新變量和函數(shù)。有關(guān) API 的完整介紹已經(jīng)超出了本文的范圍,因此我們?cè)谶@里只是簡(jiǎn)單地介紹后面在展示一個(gè)更有用的 LKM 時(shí)所使用的幾個(gè)元素。 創(chuàng)建并刪除 /proc 項(xiàng) 要在 /proc 文件系統(tǒng)中創(chuàng)建一個(gè)虛擬文件,請(qǐng)使用 create_proc_entry 函數(shù)。這個(gè)函數(shù)可以接收一個(gè)文件名、一組權(quán)限和這個(gè)文件在 /proc 文件系統(tǒng)中出現(xiàn)的位置。create_proc_entry 的返回值是一個(gè) proc_dir_entry 指針(或者為 NULL,說(shuō)明在 create 時(shí)發(fā)生了錯(cuò)誤)。然后就可以使用這個(gè)返回的指針來(lái)配置這個(gè)虛擬文件的其他參數(shù),例如在對(duì)該文件執(zhí)行讀操作時(shí)應(yīng)該調(diào)用的函數(shù)。 create_proc_entry 的原型和 proc_dir_entry 結(jié)構(gòu)中的一部分如清單 7 所示。 清單 7. 用來(lái)管理 /proc 文件系統(tǒng)項(xiàng)的元素
稍后我們就可以看到如何使用 read_proc 和 write_proc 命令來(lái)插入對(duì)這個(gè)虛擬文件進(jìn)行讀寫(xiě)的函數(shù)。 要從 /proc 中刪除一個(gè)文件,可以使用 remove_proc_entry 函數(shù)。要使用這個(gè)函數(shù),我們需要提供文件名字符串,以及這個(gè)文件在 /proc 文件系統(tǒng)中的位置(parent)。這個(gè)函數(shù)原型如清單 7 所示。 parent 參數(shù)可以為 NULL(表示 /proc 根目錄),也可以是很多其他值,這取決于我們希望將這個(gè)文件放到什么地方。表 1 列出了可以使用的其他一些父 proc_dir_entry,以及它們?cè)谶@個(gè)文件系統(tǒng)中的位置。 表 1. proc_dir_entry 快捷變量
回調(diào)函數(shù) 我們可以使用 write_proc 函數(shù)向 /proc 中寫(xiě)入一項(xiàng)。這個(gè)函數(shù)的原型如下:
filp 參數(shù)實(shí)際上是一個(gè)打開(kāi)文件結(jié)構(gòu)(我們可以忽略這個(gè)參數(shù))。buff 參數(shù)是傳遞給您的字符串?dāng)?shù)據(jù)。緩沖區(qū)地址實(shí)際上是一個(gè)用戶(hù)空間的緩沖區(qū),因此我們不能直接讀取它。len 參數(shù)定義了在 buff 中有多少數(shù)據(jù)要被寫(xiě)入。data 參數(shù)是一個(gè)指向私有數(shù)據(jù)的指針(參見(jiàn) 清單 7)。在這個(gè)模塊中,我們聲明了一個(gè)這種類(lèi)型的函數(shù)來(lái)處理到達(dá)的數(shù)據(jù)。 Linux 提供了一組 API 來(lái)在用戶(hù)空間和內(nèi)核空間之間移動(dòng)數(shù)據(jù)。對(duì)于 write_proc 的情況來(lái)說(shuō),我們使用了 copy_from_user 函數(shù)來(lái)維護(hù)用戶(hù)空間的數(shù)據(jù)。 讀回調(diào)函數(shù) 我們可以使用 read_proc 函數(shù)從一個(gè) /proc 項(xiàng)中讀取數(shù)據(jù)(從內(nèi)核空間到用戶(hù)空間)。這個(gè)函數(shù)的原型如下:
|
|