【Linux驱动】字符设备驱动模板(一)—— 驱动模块加载测试

在深入学习之前,先了解驱动最基本的架构以及驱动模块的加载,后续的内容便是在当前基础上添砖加瓦。驱动运行有两种方式:

  1. 将驱动编译进 Linux 内核,内核启动时自动运行驱动程序
  2. 将驱动编译成模块(.ko 文件),内核启动以后,使用 insmod 或 modprobe 加载驱动模块

这里我们采用第二种方式,方便调试,只需加载驱动,无需编译内核,等确定没问题以后再根据需要编译到内核。

一、最基本的驱动架构

驱动模块在被加载时,可能需要一些初始化操作,这就要用到 linux内核提供的宏:

  • module_init:注册 ko模块被加载到内核,系统会调用的函数
  • module_exit:注册 ko模块从内核卸载,系统会调用的函数
#include <linux/module.h>		// MODULE_LICENSE、MODULE_AUTHOR
#include <linux/init.h>			// module_init、module_exit

// 模块被加载时调用
static int __init chrdevbase_init(void)
{
    printk("chrdevbase init!\n");
	return 0;
}

// 模块被卸载时调用
static void __exit chrdevbase_exit(void)
{
    printk("chrdevbase exit!\n");
}
module_init(chrdevbase_init);     //注册模块加载函数 chrdevbase_init
module_exit(chrdevbase_exit);     //注册模块卸载函数 chrdevbase_exit

注意:内核中使用 printk 来输出控制台信息

二、编译驱动模块

这就需要 Makefile 来实现了,模板如下,关于模板的解析,请参考:  Linux驱动Makefile脚本解析

ARCH				:= arm
CROSS_COMPILE		:= arm-linux-gnueabihf-
CC					:= $(CROSS_COMPILE)gcc

KERNEL_DIR  		:= /home/gzx/tool/imx6ull-alientek-emmc/IMX6ULL/kernel/4.1.15/linux-imx-4.1.15-source-compiled
CURRENR_DIR			:= $(shell pwd)

MODULE_NAME			:= chrdevbase
obj-m				:= $(MODULE_NAME).o 

build: kernel_modules
kernel_modules:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURRENR_DIR) modules 
# $(CC) -o $(MODULE_NAME)App main.c

.PHONY:clean
clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURRENR_DIR) clean

输入make开始编译,编译成功后会在当前目录下生成 .ko 文件,这就是模块文件。

三、加载驱动模块

1、创建目录 /lib/modules/4.1.15

内核默认去 /lib/modules/xxx 下找模块文件,其中 xxx 是内核版本,可以使用uname -r 命令查看。如果目录不存在,需手动创建 

2、加载模块

加载模块有两种方法:insmod 和 modprobe 命令

  • insmod 命令:只会加载指定路径下的某个模块,不会解决依赖
  • modprobe:会帮忙解决依赖,也就是如果加载 a 模块需要 b 模块,那么会先加载 b 模块,再加载 a 模块

insmod 命令

命令格式:insmod  xxx.ko

root@ATK-IMX6U:/lib/modules/4.1.15# insmod chrdevbase.ko
chrdevbase init!

modprobe 命令

使用modprobe命令之前需要先使用 depmod 命令,depmod 命令会扫描一下 /lib/modules/4.1.15 目录下有哪些模块,并将结果写入到 modules.dep 文件中。

执行 depmod 以后会生成如下文件。如果出现了 could not open /lib/modules/xxx/modules.order,请参考本文结尾部分的解决方案。

接下来就是使用 modprobe 命令将模块加载到内核,加载模块不需要加上后缀!命令格式为:modprobe 模块名

root@ATK-IMX6U:/lib/modules/4.1.15# modprobe chrdevbase
chrdevbase init!

3、查看系统中存在的模块

直接输入 lsmod 命令便可查看当前系统中已经加载到内核的模块

4、卸载已存在的模块

使用 rmmod 命令卸载已经存在的模块,命令格式:  rmmod 模块名

root@ATK-IMX6U:/lib/modules/4.1.15# rmmod chrdevbase
chrdevbase exit!

四、解决 could not open /lib/modules/4.1.15/modules.order

根据提示,我们知道是因为modules.order 和 modules.builtin文件缺失。

正点原子的内核源码编译成功后,会在顶层目录下生成 modules.order 和 modules.builtin,我们只需把这两个文件拷贝到开发板的 /lib/modules/xxxx 目录下

参考文章:

Linux驱动编译报错ERROR: Kernel configuration is invalid怎么办_毛炳浩的博客-CSDN博客

imx6ull驱动开发经验_rmmod: error: ../libkmod/libkmod.c:514 lookup_buil_fhqlongteng的博客-CSDN博客

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值