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内核以后有了内核签名机制,不加上会提示模块没有签名。

编译后如下图:

Linux驱动开发-02-编译驱动程序并安装模块_自动加载

安装和卸载模块

sudo insmod hello.ko
sudo rmmod hello.ko

可以使用dmesg来查看模块的打印信息,如图:

Linux驱动开发-02-编译驱动程序并安装模块_linux_02

3. 在内核源码中编译

内核中使用Kconfig来生成make menuconfig的菜单。使用Makefile来进行编译,所以如果要在内核源码中编译自己的驱动模块,就要修改这两个文件,同时又要在make menuconfig菜单中配置选中。

先在内核源码/driver/目录下建立hello文件夹

3.1 新建Kconfig文件

内容如下

Linux驱动开发-02-编译驱动程序并安装模块_自动加载_03


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。如图

Linux驱动开发-02-编译驱动程序并安装模块_自动加载_04


Linux驱动开发-02-编译驱动程序并安装模块_#include_05

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查看模块信息

Linux驱动开发-02-编译驱动程序并安装模块_linux_06

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会卸载整组的模块