笔记:linux驱动开发(1、了解内核模块)

一个最简单的驱动模块

一个精简的驱动模块可以只有不到10行的内容,如下是一个简单的测试程序。

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

#define DEBUG(fmt, ...)         \
    do{                         \
        if(if_debug)            \
            printk(KERN_INFO "DEBUG > " fmt, ##__VA_ARGS__);   \
    }while(0)

bool if_debug = false;
/*定义一个bool类型的变量,作为一个模块入参,在装载模块时可赋值*/
module_param(if_debug, bool, S_IRUSR);

static int __init test_init(void)
{
    DEBUG("%s\r\n",__FUNCTION__);

    return 0;
}

static void __exit test_exit(void)
{
    DEBUG("%s\r\n",__FUNCTION__);
}

/*此宏声明内核模块的初始化入口点*/
module_init(test_init);
/*此宏声明内核模块的退出入口点*/
module_exit(test_exit);

/*声明开源协议*/
MODULE_LICENSE("GPL");
/*声明作者*/
MODULE_AUTHOR("wei");
/*声明模块的描述*/
MODULE_DESCRIPTION("this is a test driver");

其中module_param用以定义一个内核模块参数,可在装载(如insmod)模块时赋值,name表示变量名;type表示变量类型,目前支持有byte, short, ushort, int, uint, long, ulong,charp(字符指针),bool,invbool(和bool逻辑相反);perm表示在sysfs文件系统中该变量的权限,与文件的权限一致,可查看open接口的文档查看有哪些权限(注意其不能拥有可执行权限)。装载模块后,可在/sys/module/test/parameters/目录(视具体的驱动名而定)查看定义了哪些参数。

include/linux/moduleparam.h

#define module_param(name, type, perm)				\
	module_param_named(name, name, type, perm)
# 省掉了可执行权限
S_IRUSR  00400 user has read permission
S_IWUSR  00200 user has write permission

S_IRGRP  00040 group has read permission
S_IWGRP  00020 group has write permission

S_IROTH  00004 others have read permission
S_IWOTH  00002 others have write permission

module_init声明内核模块的初始化入口点,如果驱动采用编译进内核源码的方式,则在内核启动时运行;如果采用编译成模块的方式,则在驱动加载(如insmod)的时候运行。
module_exit声明内核模块的退出入口点,如果驱动采用编译进内核源码的方式,此函数没有作用;如果采用编译成模块的方式,则在驱动卸载(如rmmod)的时候运行。

include/linux/module.h

#define module_init(x)	__initcall(x);

#define module_exit(x)	__exitcall(x);

驱动编译的Makefile

下面是一个通用的编译驱动的Makefile,KERNEL_DIR表示内核源码树的位置;obj-m表示生成的目标文件名;-C选项可以改变当前的工作目录,即到内核源码的根目录;M指定要编译的模块源码目录;modules是顶层Makefile里面的伪目标。

KERNEL_DIR=/home/Desktop/s5pv210/linux-5.7.8

obj-m := test.o

all:
	# 执行内核源码根目录里面的Makefile的modules伪目标将当前
	目录内容编译成内核模块
	$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules
clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean

相关命令

命令描述
lsmod显示当前已加载的驱动模块
insmod装载驱动模块
rmmod卸载驱动模块
modinfo显示驱动模块的相关信息
depmod检测驱动模块之间的依赖关系
modprobe也用于加载驱动模块,但会先检测驱动模块之间的依赖关系,依次加载依赖的模块

通过前面写的测试模块程序测试如上的相关命令:

modinfo test.ko

# 效果
filename:       test.ko
author:         wei
description:    this is a test driver
license:        GPL
depends:
vermagic:       5.7.8 preempt mod_unload ARMv7 p2v8
# 未给内核模块传参
insmod test.ko

# 效果
# 可在/sys/module/目录看到生成了对应的模块目录,也可
# 用dmesg命令查看日志

rmmod test.ko

# 效果
# 可看到/sys/module/目录里面对应的模块目录被移除
# 给内核模块传参
insmod test.ko if_debug=1

# 效果
# 能够输出调试信息
DEBUG > test_init

rmmod test.ko

# 效果
# 能够输出调试信息
DEBUG > test_exit

错误解决:

先在lib目录下创建modules目录,并在modules目录下创建5.7.8(视具体内核版本而定)目录,执行depmod命令,执行完后会在/lib/modules/5.7.8/目录下生成modules.dep.bb文件,然后使用mv命令重命名该文件为modules.dep即可。

modinfo: can't open '/lib/modules/5.7.8/modules.dep': No such file or directory

欢迎扫码关注我的微信公众号
漫长当下

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值