当前位置: 首页 > article >正文

笔记整理—linux驱动开发部分(2)模块信息与编译

        对于linux而言,.ko文件为驱动文件,在终端可以使用lsmod列出已经安装的模块,使用insmod xxx.ko安装所需要的模块,modinfo xxx.ko打印某个模块提供的信息,rmmod xxx卸载某个不需要的模块。

        insmod与module_init宏。在源代码中,使用宏声明了一个函数,使用module_init()宏对宏内的函数进行insmod的绑定,insmod中会去执行宏所绑定的函数。dmsg指令可看见函数内打印。

        module_exit宏与rmmod。也是一种module_exit()宏对函数的绑定与rmmod对其内函数的执行。

        insmod的version magic与zImage中的version magic因一模一样,否则会导致驱动模块安装不了,这是一种安全措施。

        如何保证内核源代码树与模块内核源代码一样(version magic)保证两个用的是同一个内核源码树即可。

        模块的常用宏可用modinfo查看。

        MODULE_xxx宏用于添加模块描述信息,MODULE_LICENSE("GPL")为许可证信息为GPL,GPL是指内核为GPL的内核;MODULE_AUTHOR()为作者描述;MODULE_DESCRIPTION()为模块描述(作用);MODULE_ALIAS()模块别名。

        函数修饰符:

static int __init chrdev_init(void);
static void __exit chrdev_exit(void);

        __init是一个宏,一个内核宏,与段相关,放入.init.text段默认为.text段。__exit也是一个宏把这个函数.exit.text段默认为.text段。所有__init的函数是被统一存在特定地方的,因为安装是一次性的,所以安装完成后这个段会被释放,__exit同理。

        printk()只能在内核范围使用,printf的调试信息一般为全开或全关,但在内核中的整体调试时,要善用打印级别做调试信息打印,可以靠更改打印级别控制可见信息输出。

        <linux/module.h>里存放了module_init;和module_exit。 <linux/init.h>存放了__init;和__exit。驱动头文件与应用层头文件不同,应用层头文件由编译器提供,驱动由内核提供(内核源码)/include/linux/xxx/xxx.h。

        MAKEFILE分析,KERN_DIR= 这是内核源码树目录,obj-m+=xxx.o编译目标xxx.c对应,-m是将其编译为一个模块。

make -c $(KERN_DIR) M='pwd' modules

        本质上是make modules,进入内核源码树中用内核模块规则进行模块编译,完成后把文件移动回来。KERN_DIR=/Root/driver/kernel要精准到kernel的位置就行。

        内核启动后会打印释放init段的内存大小。

        嵌入式系统工作原理:应用层——>API——>设备驱动——>硬件。

        API指write、read、open、close等,驱动源码中应该提供这些API实体。

        flie_operations结构体:

struct file_operations {
	struct module *owner;
	loff_t (*llseek) (struct file *, loff_t, int);
	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
	int (*readdir) (struct file *, void *, filldir_t);
	unsigned int (*poll) (struct file *, struct poll_table_struct *);
	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
	int (*mmap) (struct file *, struct vm_area_struct *);
	int (*open) (struct inode *, struct file *);
	int (*flush) (struct file *, fl_owner_t id);
	int (*release) (struct inode *, struct file *);
	int (*fsync) (struct file *, int datasync);
	int (*aio_fsync) (struct kiocb *, int datasync);
	int (*fasync) (int, struct file *, int);
	int (*lock) (struct file *, int, struct file_lock *);
	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
	int (*check_flags)(int);
	int (*flock) (struct file *, int, struct file_lock *);
	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
	ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
	int (*setlease)(struct file *, long, struct file_lock **);
};

        包装了多种函数指针,使驱动接口与API相接,挂接实体函数;设备驱动向内核注册时提供该结构体类型变量;每个驱动都有这样的一个结构体。

        注册函数是由内核提供的,注册前驱动是用不了的,注册是向内核进行注册,注册后驱动就有了登记可以使用。


http://www.kler.cn/a/372622.html

相关文章:

  • Linux 练习三
  • 论文提交步骤 | 2024年第五届MathorCup大数据竞赛
  • SQL语言基础
  • 设计产品宣传册没头绪?推荐一个超多产品宣传册、画册的案例网站
  • sql进阶篇
  • 基于spootboot学生选课系统设计与实现
  • 记录一次查询优化
  • 关于Mac打包ipa的配置小结
  • Hyperledger Fabric有那些核心技术,和其他区块链对比Hyperledger Fabric有那些优势
  • Spring Boot 实现文件分片上传和下载
  • 运维端口号详解(Detailed Explanation of Operation and Maintenance Port Numbers)
  • 高效MySQL缓存策略
  • C++(运算符重载)
  • iQOO手机怎样将屏幕投射到MacBook?可以同步音频吗?
  • 【Searxng】Searxng docker 安装
  • 《IMM交互式多模型滤波MATLAB实践》专栏目录,持续更新……
  • 基于Django+python的车牌识别系统设计与实现(带文档)
  • CentOS 7 下升级 OpenSSL
  • w外链如何跳转微信小程序
  • 快速上手 Rust——环境配置与项目初始化
  • 【C++刷题】力扣-#594-最长和谐子序列
  • vue添加省市区
  • 【Gorm】自定义数据类型
  • MacOS的powermetrics命令查看macbook笔记本的耗能情况,附带查看ANE的工作情况
  • 基于单片机的恒流源技术研究
  • ADS8320E/2K5 数据手册ADS8320一款16位模数转换器 A/D转换器芯片