在Ubuntu 18.04環境下編寫一個簡單的核心模組
阿新 • • 發佈:2018-12-14
我們首先來看看核心模組的定義
模組是具有獨立功能的程式,可以單獨編譯,但是不能單獨執行。模組在執行時,會被連結到核心,作為核心的一部分在核心空間執行。模組通常由一組函式和資料結構組成,用來實現一種檔案系統、驅動程式或其他核心上層的功能。
實驗環境: Ubuntu 18.04 + 4.15.0
編寫模組
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
static int __init lkp_init(void)
{
printk("<1>Hello, World! from the kernel space...\n" );
return 0;
}
static void __exit lkp_cleanup(void)
{
printk("<1>Good Bye, World! leaving kernel space...\n");
}
module_init(lkp_init); // 註冊模組
module_exit(lkp_cleanup); // 登出模組
MODULE_LICENSE("GPL"); //告訴核心該模組具有GNU公共許可證
- module.h標頭檔案中包含了對模組的結構定義以及模組的版本控制
- kernel.h包含了常用的核心函式
- init.h包含巨集__init和__exit,__init告訴編譯器,這個函式或者變數僅用於初始化,編譯程式將所有的__init程式碼儲存到特殊的記憶體段中,初始化結束後,記憶體被釋放
- module_init()/exit(),向核心註冊/登出模組提供新功能
編寫Makefile檔案
什麼是Makefile檔案?
Makefile檔案就是用一組約定好的語法規則,告訴make命令,怎麼樣連結和編譯程式,帶來的好處就是自動化編譯。
在當前目錄下,建立Makefile檔案,比如可以用命令
touch Makefile
在檔案中輸入以下程式碼
# Makefile 4.0 obj-m := testKernel.o CURRENT_PATH := $(shell pwd) LINUX_KERNEL := $(shell uname -r) LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL) all: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules clean: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
- obj-m := 這是一個賦值語句,說明要使用目標檔案testKernel.o建立一個模組
- 後面幾條語句都是常見的shell命令
編譯檔案
直接在當前目錄下,在控制檯中輸入make。對於ubuntu自帶的原始的核心檔案,遇到如下錯誤 按照提示,缺少庫檔案,我們只需要安裝一個即可。
sudo apt-get install libelf-dev
安裝完成之後,再次編譯 至此,編譯完成,會在當前目錄生成以下檔案
插入模組,並且執行
使用insmod插入核心模組
insmod testKernel.ko
檢測是否正確插入
lsmod | grep testKernel
模組使用的函式printk()會預設列印系統檔案/var/log/syslog(之前ubuntu的版本本日誌存放在/var/log/messages),輸入以下命令,檢視messages是否輸出了我們想要的資訊。
解除安裝模組
使用rmmod命令解除安裝模組
rmmod testKernel
從如下訊息中,可以看出解除安裝成功 以上就是一個簡單的核心模組從編譯到解除安裝的過程