模塊編寫
-
入口函數
int __init xxx_func(void) { } module_init(xxx_func);
-
出口函數
void __exit xxx_func(void) { } module_exit(xxx_func);
-
模塊信息聲明
MODULE_AUTHOR("whuer Xiaojie <[email protected]>"); MODULE_LICENSE("GPLv2"); MODULE_DESCRIPTION("A simple test module!");
內核模塊加載
- 靜態加載(把模塊編譯進內核,通過修改內核進行編譯)
-
將編寫好的源代碼複製到Linux內核源代碼的相應目錄中
-
在目錄的Kconfig文件中增加關於新代碼對應項目的編譯配置選項
-
在目錄的Makefile文件中增加對應的新代碼的編譯條目
缺點:
是這樣編譯出來的內核鏡像會變大,且得重新編譯內核所有源代碼,比較麻煩,一般項目打包的時候才需要這樣做
- 動態加載
-
$ sudo lsmod
查看內核已經安裝的所有模塊(內核中已加載的內核模塊存放於sys/module
目錄下) -
$ sudo insmod XXX.ko
加載模塊到內核(加載函數會被調用)也可以使用$ sudo modprobe XXX.ko
,該命令功能強大,在加載內核模塊的同時會加載該模塊所依賴的其他模塊 -
$ rmmod XXX
移除模塊(卸載函數會被調用)$ modeprobe -r XXX
卸載通過modprobe
加載的模塊 -
$ dmesg
查看內核debug信息$dmesg -C
清空所有歷史debug信息 -
內核模塊的加載和卸載函數只會被執行一次
-
$ modinfo XXX
查看模塊的信息
Makefile格式如下:
#current path
PWD = $(shell pwd)
# kernel version
KVERS =$(shell uname -r)
#kernel dir
KERNDIR =/lib/modules/${KVERS}/build/
#Specify flags for module compilation
#EXTRA_CFLAGS =-g -o0
#kernel modules
obj-m += hello.o
# for multi source code file suce file1.c file2.c
# obj-m += modulename.o
# modulename-objs +=file1.o file2.o
build: kernel_modules
kernel_modules:
make -C $(KERNDIR) M=$(PWD) modules
clean:
make -C $(KERNDIR) M=$(PWD) clean
DEMO
#include <linux/init.h>
#include <linux/module.h>
static int __init hello_init(void)
{
printk(KERN_INFO "%s: init called\n", __func__);
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "%s: exit called\n",__func__);
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Whuer Xiaojie <[email protected]>");
MODULE_LICENSE("GPLv2");
MODULE_DESCRIPTION("A simple test module!");