1. 说明
编译驱动程序既可以在内核源码中进行,这样可以通过make menuconfig来配置,也可以通过使用源码环境而不在源码中编译。生成ko文件,自己进行安装模块。
在内核源码中编译后生成的内核镜像文件包含该模块,启动内核时,模块自动加载。这种方式又称为静态加载。响应的,不把模块编译进内核,而使用命令加载的方式称为动态加载。
2. 不在内核源码中编译
源码
这种方式比较简单,主要在于Makefile文件的编写。直接上源码。
hello.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void){
printk("Hello World enter\n");
return 0;
}
static void hello_exit(void){
printk("Hello World exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("AIZIZAI");
MODULE_DESCRIPTION("A simple Hello World Module~");
MODULE_ALIAS("a simpliest module");
Makefile
CONFIG_MODULE_SIG=n
ifeq ($(KERNELRELEASE),)
ARCH=x86_64
PWD:= $(shell pwd)
CROSS_COMPILE=x86_64-linux-gnu-
CC=$(CROSS_COMPILE)gcc
KERNELDIR=/usr/src/linux-source-4.4.0
hello.ko: hello.c
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNELDIR) M=$(PWD) modules
else
obj-m += hello.o
endif
hello: hello.c
arm-linux-gnueabi-gcc $< -o $@ -g
clean:
rm -rf *.o *.ko *.mod.c .*.cmd *.markers *.order *.symvers .tmp_versions hello
其中 CONFIG_MODULE_SIG=n是因为自3.7内核以后有了内核签名机制,不加上会提示模块没有签名。
编译后如下图:
安装和卸载模块
sudo insmod hello.ko
sudo rmmod hello.ko
可以使用dmesg来查看模块的打印信息,如图:
3. 在内核源码中编译
内核中使用Kconfig来生成make menuconfig的菜单。使用Makefile来进行编译,所以如果要在内核源码中编译自己的驱动模块,就要修改这两个文件,同时又要在make menuconfig菜单中配置选中。
先在内核源码/driver/目录下建立hello文件夹
3.1 新建Kconfig文件
内容如下
hello module 就是make menuconfig的菜单名
3.2 修改上层(driver目录下的)Kconfig
添加内容如下:
source "drivers/hello/Kconfig"
3.3 修改Makefile 如下
obj-$(CONFIG_HELLO) += hello/
3.4 在make menuconfig中选中模块
路径:Driver Device - hello module。如图
3.5 编译
aizizai@ubuntu:/usr/src/linux-source-4.4.0$ sudo make -j12
编译后结果
aizizai@ubuntu:/usr/src/linux-source-4.4.0/drivers/hello$ ls
built-in.o hello.c hello.ko hello.mod.c hello.mod.o hello.o Kconfig Makefile modules.builtin modules.order
使用modinfo查看模块信息
4. 更多
自动安装模块
sudo cp hello.ko /lib/modules/$(uname -r)/kernel/
sudo depmod
sudo modprobe hello
depmod 命令用于生成 modules.dep 和 map 文件,该文件用于在启动时 modules 自动加载。该命令生成的文件是 modules 之间依赖的一个列表。
modprobe可载入指定的个别模块,或是载入一组相依的模块。modprobe会根据depmod所产生的相依关系,决定要载入哪些模块。若在载入过程中发生错误,在modprobe会卸载整组的模块