环境:ubuntu 16.04
HelloWorld模块在内核运行时即插即用,也可随时移除。
1、构建内核源代码库
查看显示操作系统的发行版号:
uname -r : 显示操作系统的发行版号 uname -a : 显示系统名、节点名称、操作系统的发行版号、内核版本等等
下载对应版本内核源码:
sudo apt-get install linux-source-4.15.0
下载完成后如下:
解压代码:
tar jxvf linux-source-2.6.20.tar.bz2
进入linux-source-4.15.0配置内核,选择最快的原版的配置
make oldconfig
需要切换到root目录执行
解下来编译bzImage
make bzImage
make bzImage时报错scripts/sign-file.c:23:30: fatal error: openssl/opensslv.h: No such file or directory
sudo apt-get install libssl-dev
接下来
make modules
这个过程时间较长大约两个小时
接下来执行
make modules_install
执行完会在/lib/modules/看到4.15.0-45-generic编译模块文件时,要用到这个路径下的build目录。
2、编写驱动代码
#include <linux/init.h> #include <linux/module.h> //告知内核,模块拥有开源许可证 MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_EMERG "Load Hello World "); return 0; } static void hello_exit(void) { printk(KERN_EMERG "Rmmove Hello World "); } module_init(hello_init); module_exit(hello_exit);
上述代码表示:在内核加载该模块是执行hello_init,在模块被移除是调用hello_exit。
printk为内核的打印函数,因为内核无法使用C语言库代码,所以无法使用printf。
编写Makefile文件
obj-m := hello.o KERNELDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
然后执行make进行编译
执行后结果如下:
我们需要的是hello.ko文件
insmod hello.ko
insmod 加载模块
rmmod hello.ko
rmmod 移除模块
可见模块在加载时打印了Load Hello World,模块在移除是打印Rmmove Hello World。