【内核驱动】编译和加载内核驱动模块

00. 目录

01. 概述

对于linux内核,可以通过两种方式将内核模块添加到内核中:

  • 1、将内核模块编译成内核模块文件,在内核启动后由用户手动动态加载,
  • 2、将模块直接编译到内核中去,内核启动时自动加载。

02. 测试代码

test.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>

static int __init hello_init(void)
{
    
    
    printk(KERN_EMERG "Hello  Module Init\n");
    return 0;
}

static void __exit hello_exit(void)
{
    
    
    printk(KERN_EMERG "Hello  Module Exit\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("uplooking");
MODULE_DESCRIPTION("hello module");
MODULE_ALIAS("test_module");

03. 内核模块编译

内核驱动模块对象所需的构建步骤和编译很复杂,它利用了linux内核构建系统的强大功能, 当然我们不需要深入了解这部分知识,利用简单的Make工具就能编译出我们想要的内核驱动模块。

Makefile参考如下

KERNEL_DIR=/home/deng/code/x3399/kernel
CROSS_COMPILE=aarch64-linux-gnu-gcc

obj-m := test.o

all:
	$(MAKE) -C $(KERNEL_DIR) M=`pwd` modules

.PHONE:clean
clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean

  • 第1行: 指定编译内核存放位置
  • 第2行: 指定交叉编译工具链
  • 第3行: 表示以模块编译
  • 第4行: all只是个标号,可以自己定义,是make的默认执行目标。
  • 第5行: $(MAKE):MAKE是Makefile中的宏变量,要引用宏变量要使用符号。这里实际上就是指向make程序,所以这里也可以把$(MAKE)换成make.-C:是make命令的一个选项,-C作用是changedirectory. -C dir 就是转到dir目录。M=pwd:返回当前目录。这句话的意思是:当make执行默认的目标all时,-C(KERNEL_DIR)指明跳转到内核源码目录下去执行那里的Makefile,-C $(KERNEL_DIR)指明跳转到内核源码目录下去执行那里的Makefile,M=pwd表示又返回到当前目录来执行当前的Makefile.
  • 第6行: clean 就是删除后面这些由make生成的文件。

查看当前文件夹,新增test.ko,这就是我们自己编写、编译的内核驱动模块。

在这里插入图片描述

deng@local:~/code/test/1module$ make 
make -C /home/deng/code/x3399/kernel M=`pwd` modules
make[1]: 进入目录“/home/deng/code/x3399/kernel”
  CC [M]  /home/deng/code/test/1module/test.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/deng/code/test/1module/test.mod.o
  LD [M]  /home/deng/code/test/1module/test.ko
make[1]: 离开目录“/home/deng/code/x3399/kernel”
deng@local:~/code/test/1module$ 


deng@local:~/code/test/1module$ ls
Makefile       Module.symvers  test.ko     test.mod.o
modules.order  test.c          test.mod.c  test.o
deng@local:~/code/test/1module$ 

04. 内核模块加载和卸载

编译好内核驱动模块,可以通过多种方式将test.ko拷贝到开发板,一般主要使用NFS网络文件系统或者SCP命令。

加载模块

[root@rk3399:/mnt/code/test/1module]# ls
Makefile	modules.order  test.ko	   test.mod.o
Module.symvers	test.c	       test.mod.c  test.o
[root@rk3399:/mnt/code/test/1module]# insmod test.ko
[  652.669514] Hello  Module Init
[root@rk3399:/mnt/code/test/1module]# 

卸载模块

[root@rk3399:/mnt/code/test/1module]# rmmod test
[  668.206247] Hello  Module Exit
[root@rk3399:/mnt/code/test/1module]# 

05. 问题讨论

06. 附录

猜你喜欢

转载自blog.csdn.net/dengjin20104042056/article/details/132871465