一.創建函數文件和Makefile文件
$sudo mkdir qiliguala
$cd qiliguala
$vim helloworld.c
在helloworld.c下輸入以下內容
#include <linux/init.h> //模塊的初始化的宏定義 以及一些其他函數的初始化函數
#include <linux/kernel.h> //包含了printk函數
#include <linux/module.h> ////動態的將模塊加載到內核中去
static int __init lkm_init(void)
{
printk("Hello World\n");
return 0;
}
static void __exit lkm_exit(void)
{
printk("Goodbye\n");
}
module_init(lkm_init);
module_exit(lkm_exit);
MODULE_LICENSE("GPL"); //GPL許可證
include包含就不詳細說了,很重要,必須要有。
static int __init lkm_init(void)中 __init 比較有意思,百度給的解釋是(宏定義__init,用於告訴編譯器相關函數或變量僅用於初始化。編譯器將標__init的所有代碼存在特殊的內存段中,初始化結束後就釋放這段內存。)
我的理解就是釋放內存
module_init(lkm_init);就是對函數進行聲明
MODULE_LICENSE(“GPL”);模塊驅動聲明
$vim Makefile
輸入以下內容
obj-m:=helloworld.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:=helloworld.o,我認爲就是生產.o文件
CURRENT_PATH指當前地址
LINUX_KERNEL指內核版本號
LINUX_KERNEL_PATH內核地址
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
以上兩句就是在內核中生成的文件
二.編譯
輸入
$make
進行編譯
輸入ls,發現生成了很多文件
此時並沒有在終端顯示信息,因爲這裏內核和終端沒有聯繫,內核不將信息打印到終端上
三.打印
我們輸入
lsmod
出現helloworld就說明我們已經將helloworld這個模塊插入到內核中去了
再輸入
$dmesg
就可以發現打印了
刪除,輸入
$sudo rmmod helloworld
$lsmod
會發現helloworld模塊已經從內核中刪除
再輸入
$dmesg
此時打印出goodbye