i.MX6ULL驱动开发 | 01-Linux内核模块的编写与使用

春衣少年当酒歌,起舞四顾以笑和。这篇文章主要讲述i.MX6ULL驱动开发 | 01-Linux内核模块的编写与使用相关的知识,希望能为你提供帮助。


一、Linux内核模块Linux内核中提供了?模块(Module)?机制,具有以下优点:


  • 模块不会被编译到linux内核中
  • 使用的时候,动态加载进内核
  • 不需要的时候,从内核卸载

二、Linux内核模块的编写 1. 头文件
#include < linux/init.h>
#include < linux/module.h>

2. 模块加载函数当模块被加载进内核时,系统会调用模块的?模块加载函数?,该函数使用??__init??来标识。
static int __init module_demo_init(void)

printk("module demo init success!");
return 0;

module_init(module_demo_init);

在编写时,若初始化成功应该返回0,若初始化失败应该返回错误编码,方便用户程序利用perror等方法将它们转换为有意义的错误信息字符串。
3. 模块卸载函数当模块从内核被卸载时,系统会调用模块的?模块卸载函数?,该函数使用??__exit??来标识。
static void__exit module_demo_exit(void)

printk("module demo exit success!");

module_exit(module_demo_exit);

4. 模块参数 5. 模块声明与描述

  • MODULE_AUTHOR:模块作者
  • MODULE_DESCRIPTION:模块描述
  • MODULE_VERSION:模块版本
  • MODULE_DEVICE_TABLE:设备表
  • MODULE_ALIAS:别名

MODULE_AUTHOR("mculover666 < mculover666@qq.com> ");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("A example Module");

至此,一个简单的基本的内核模块编写完成。
三、Linux内核模块的编译编写一个Makefile,和模块源码位于同一个目录:
KERNEL_DIR := /home/mculover666/imx6ull/kernel/linux-imx6ull

# Kernel modules
obj-m += module_demo.o

# Specify flags for the module compilation.
#EXTRA_CFLAGS=-g -O0

build: kernel_modules

kernel_modules:
make -C $(KERNEL_DIR) M=$(CURDIR) modules

clean:
make -C $(KERNEL_DIR) M=$(CURDIR) clean

编译:
make

注意,?模块编译也属于内核代码编译,所以在make之前,需要设置ARCH和CROSS_COMPILE环境变量?。
编译完成后,在当前路径下会生成??.ko??文件,这个便称之为内核模块。
四、Linux内核模块的使用 1. 加载模块与卸载模块使用 insmod命令加载模块:
insmod < 模块名称.ko>

i.MX6ULL驱动开发 | 01-Linux内核模块的编写与使用

文章图片

使用 rmmod 命令卸载模块:
rmmod < 模块名称>

i.MX6ULL驱动开发 | 01-Linux内核模块的编写与使用

文章图片

2. 查看系统中已加载的所有模块
lsmod

i.MX6ULL驱动开发 | 01-Linux内核模块的编写与使用

文章图片

lsmod命令实际上是读取并分析??/proc/modules??文件:
i.MX6ULL驱动开发 | 01-Linux内核模块的编写与使用

文章图片

内核中已加载模块的信息也存在于??sys/module??目录下,加载module_demo.ko后,内核中将包含??/sys/module/module_hello??目录:
i.MX6ULL驱动开发 | 01-Linux内核模块的编写与使用

文章图片

该目录下又有一个refcnt文件和一个sections目录,
i.MX6ULL驱动开发 | 01-Linux内核模块的编写与使用

文章图片

3. modprobe命令modprobe命令要比insmod命令强大,它在加载模块时,会同时加载该模块依赖的其它模块:
modprobe < 模块名称.ko>

通过modprobe加载的模块,可以通过modprobe卸载,?将卸载其依赖的模块?:
modprobe -r < 模块名称.ko>

模块之间的依赖关系存放在根文件系统的 ??/lib/modules/< kernel-vesion> /modules.dep?? 文件中,该文件是在整体编译内核时,由depmod工具生成的。
4. modinfo命令
modinfo < 模块名>

使用该命令可以获得模块的信息,包括模块作者、说明等等。
参数资料
  • 《Linux设备驱动开发详解:基于最新的Linux 4.0内核》,宋宝华
【i.MX6ULL驱动开发 | 01-Linux内核模块的编写与使用】


    推荐阅读