Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 內核模組開發入門:Hello World 到參數傳遞、符號導出與模組生命週期

編輯:Linux 教學

內核模組是動態載入的內核代碼,運行在內核態(Ring 0),具有完全硬件訪問權限。本文從最小模組入手,涵蓋 Makefile、編譯載入、初始化/清理、用戶態交互、符號導出、版本依賴等核心知識點。

最小內核模組:Hello World

源碼 hello.c

#include 
#include 

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Developer");
MODULE_DESCRIPTION("Minimal kernel module");

static int __init hello_init(void) {
    printk(KERN_ALERT "HELLO WORLD\n");
    return 0;  // 非 0 表示初始化失敗,模組不會被載入
}

static void __exit hello_exit(void) {
    printk(KERN_ALERT "GoodBye\n");
}

module_init(hello_init);
module_exit(hello_exit);

關鍵點解析

  • __init:標記初始化函數,載入後釋放其代碼段內存(.init.text 區)
  • __exit:標記清理函數,僅在模組移除時調用,內建內核時被優化掉
  • printk:內核打印,級別 KERN_ALERT 等,輸出至內核環形緩衝區(dmesg 查看)
  • MODULE_LICENSE:聲明許可證,專有許可會污染內核(tainted),影響技術支援

Makefile:內核建構系統整合

obj-m := hello.o
KDIR := /lib/modules/$(shell uname -r)/build

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
	$(MAKE) -C $(KDIR) M=$(PWD) clean
	rm -f *.ko *.o *.mod.* *.symvers *.order

機制:KERNELRELEASE 變量區分內核樹建構 vs 外部建構。modules 目標觸發模組編譯並生成 .ko。

編譯、載入、驗證、卸載

# 編譯(需內核頭文件包:kernel-devel / linux-headers-$(uname -r))
make

# 載入(需 root)
insmod hello.ko
dmesg -T | tail -2   # 查看輸出

# 列出已載入模組
lsmod | grep hello

# 卸載
rmmod hello
dmesg -T | tail -1

模組參數:用戶態傳遞配置

static char *whom = "world";
static int count = 1;
module_param(whom, charp, 0644);
module_param(count, int, 0644);
MODULE_PARM_DESC(whom, "Greeting target");
MODULE_PARM_DESC(count, "Repeat count");

static int __init hello_init(void) {
    for (int i = 0; i < count; i++)
        printk(KERN_ALERT "Hello, %s!\n", whom);
    return 0;
}

載入時傳參:insmod hello.ko whom="kernel" count=3

符號導出:模組間共享

// 導出函數/變量供其他模組使用
EXPORT_SYMBOL(my_function);
EXPORT_SYMBOL_GPL(my_gpl_function);  // 僅 GPL 模組可用

依賴關係:modprobe 會自動解析 modules.dep 載入依賴模組;insmod 不會。

版本依賴與 vermagic

  • 模組必須對目標內核版本重新編譯
  • 編譯時鏈接 vermagic.o,嵌入內核版本、GCC 版本、配置選項(CONFIG_SMP、CONFIG_PREEMPT 等)
  • modinfo hello.ko | grep vermagic 查看
  • 強制載入(極不推薦):insmod --force 或修改 vermagic 字符串

用戶空間 vs 內核空間

當前進程上下文

模組代碼多在進程上下文執行(系統調用、文件操作、ioctl)。獲取當前 task_struct:

#include 
struct task_struct *task = current;  // 宏展開為 get_current()
printk("PID: %d, Comm: %s\n", task->pid, task->comm);

常用工具鏈

  • insmod/rmmod/lsmod/modinfo:基礎操作
  • modprobe:智能載入(解析依賴)
  • dmesg -T / journalctl -k:內核日誌
  • cat /proc/modules:模組列表(lsmod 來源)
  • trace-cmd / perf:動態追蹤
Copyright © Windows教程網 All Rights Reserved
特性用戶態應用內核模組
地址空間獨立虛擬地址空間共享內核地址空間
庫函數glibc 等僅內核導出符號(無 libc)
錯誤處理段錯誤僅殺死進程Oops/Panic 可致系統崩潰
併發進程/線程中斷、軟中斷、多 CPU 並行
調試GDB、stracekgdb、ftrace、printk、crash