[学习]Linux drivers


本文,记录学习linux驱动的思考过程。

这是在编写了 [解读]Hi3519-图像处理-专业名词之后,学习到的一种新的笔记书写方式,但目前暂时还未能够说出该方式的一种比较专业的理论,但按照感觉走,还是不错的。该方式优势在于:
  1. 主题非常鲜明 ,消除拖沓,不跟随书本的目录,源思考路径可寻
  2. 点明提供解决问题的思路,并为此提供链接,可以重复修改
  3. 内容极端简洁,摒弃冗余

本文首先在2017/2/25 21:33编写,做出第一次书写,明天就将深入其中每一个细节,并且修改和补充笔记。(这是新笔记的回顾方式)


参考资料
  1. 《嵌入式Linux开发教程(下册)》


基础知识记录最为关键的知识结构,稍作备注,不作展开。

>>> 2.1内核模块,获取
  1. 头文件 <linux/module.h>和<linux/init.h>,构建只有入口与出口的内核模块
  2. 编译注意事项,内核树之外编译内核模块的通用Makefile文件(程序清单2.3)
  3. 加载与卸载(定义 __init与 __exit和 module_init与 module_exit),内核打印printk
  4. 最简单的内核模块(程序清单2.4)
其升级版是:带参数的内核模块(程序清单2.5)
注意:这里讲述的是内核模块,内核模块不止是驱动。


>>> 2.2设备分类,获取
  1. 设备类型(字符c,块b,网络)
  2. 设备文件(执行 ls -l /dev/mem即可,解析图2-1),设备编号( dev_t结构表示编号组成,头文件<linux/kdev_t.h>的宏静态获取设备号)
  3. 设备节点和设备号( cat /proc/devices查看,头文件 <linux/fs.h>获取与释放设备号--动态与静态)
  4. 设备的注册和注销(头文件 <linux/cdev.h>,结构struct cdev描述字符设备结构)
注意:这里讲述的是设备,设备不止是硬件设备,也就常说的硬件,用户想去控制的。


>>> 2.3设备驱动,获取:
  1. 驱动的入口与出口(程序清单2.11)
  2. 支持udev动态设备的驱动范例(程序清单2.14,头文件 <linux/device.h>)
  3. 以fops数据结构为核心的设备驱动程序实现操作设备的方法(头文件 <linux/fs.h> )
    1. 图2.4fops在设备驱动和系统调用之间的关系(用户空间->设备)
    2. 典型字符驱动框架缩略图--图2.6
    3. 字符驱动测试用例(程序清单2.18)


>>> LED完整驱动示例,获取:
  1. ioctl命令构成(一个32位数据,分成多部分来构造命令)
  2. 构造ioctl命令(ioctl的第二个参数cmd,分别设置不同cmd的幻数、功能号、数据大小),构造命令解析
  3. 解析命令(传输方向、命令类型、命令编码、参数大小)
  4. 内核ioctl与用户ioctl(两个接口有所不同)
  5. LED驱动实现示例(程序清单2.20,版本兼容处理头文件 <linux/version.h>)以及测试用例(提出驱动所有命令都应该由用户测试完成,一般包含偷文件即可)


>>> 内核/用户空间的数据交换,获取:
  1. 地址合法检测(内核提供检测与非检测的两种传递数据工具--函数,看是否带__)
  2. 辅助单个或多个数据(put/get为单个--单个数据针对arm而言的并非一个字节,copy为多个--即数据块;头文件<asm/uaccess.h>)
  3. 设备读写方法实现的驱动示例(程序清单2.22)以及测试用例(读写回传判断数据是否正确)


>>> 使用中断的驱动,获取:
  1. 中断的申请与释放(头文件 </linux/interrupt.h>,中断号、中断是否屏蔽、IRQ指针、设备指针)
  2. 触发条件(头文件 <linux/irq.h>)
  3. 中断的使能与禁止,最为关键的是:IRQ处理函数编写
  4. 按键驱动示例(程序清单2.25)以及测试用例(查看系统中断次数 cat /proc/interrupts)


完整示例
LED驱动

多种实现办法,其一是传统的字符设备驱动,其二是利用LED子系统,其三是特定的mx28平台驱动模型

>>> 传统的字符设备驱动:程序清单2.20
  1. 调用imx28x的BSP所实现的GPIO底层接口移植,需要操作硬件资源

>>> LED子系统:程序清单3.1--3.6
  1. 仅修改一个关键函数,驱动加载后会出现在led子系统上

>>> 平台驱动模型:程序清单3.7--3.12
  1. 暂时没看,因为这感觉不太好用。

点评:前两种较好,第一种灵活,第二种移植性强

按键驱动

两种实现方法,其一是传统的字符设备驱动,其二是将按键纳入Linux的输入子系统,重新实现按键功能。

>>> 传统的字符设备驱动(中断),获取:

>>> 输入子系统,获取:
  1. 内容是有点多,暂时不整理


释放疑问

>>> 内核模块编译,获取:
  1. 编译需要使用内核源码,编译模块的内核配置与所运行内核的编译配置一致(版本,内核树一致)。
  2. 直接在虚拟机ubantu上运行内核模块,下载目前内核运行的内核源码
备注: 参考链接

>>> 设备与驱动的关系,获取:
  1. 驱动是 Linux 系统中设备和用户之间的桥梁, Linux 系统中,访问设备必须通过设备驱动进行操作,用户程序是不能直接操作设备的。(示意图2-2,硬件、驱动、用户的关系)。这里,其实驱动,全名应该是设备驱动。
  2. 设备有软硬、虚拟真实的设备;驱动是操作某一类设备的操作程序。
  3. linux的设备节点(也就是目录/dev显示的设备文件),专门处理设备;而驱动则是由ko文件组成,并且insmod或rmmod装载或卸载驱动
  4. 执行过程如下:
    1. 当程序打开一个设备文件时,内核就可以获取对应设备的设备类型、主设备号和次设备号等信息,内核也就知道了程序需要操作使用哪个设备驱动程序。在程序随后对这个文件的操作都会调用相应的驱动程序的函数,同时把设备号传递给驱动程序。(理解内核执行过程)
    2. 主设备号标识设备对应的驱动程序,告诉 Linux 内核使用哪个驱动程序驱动该设备。如果多个设备使用同一个驱动程序,则它们拥有相同的主设备号。例如/dev/ttyS0~3 这 4 个设备,拥有相同的主设备号 4,说明它们使用同一份驱动。(理解设备号与驱动的关系)
    3. 设备注册后,该设备的主设备号fops 之间对应关系就一直存在于内核中,直到驱动生命周期结束(被卸载),应用程序发起系统调用,内核根据这个对应关系寻找正确的驱动程序执行相关操作。(系统调用和驱动方法关系)。过程如下:
      1. 用户程序系统调用打开/dev/char设备文件,获得主次设备号;
      2. 根据主设备号,寻找对应的fops;
      3. 找到对应的fops,执行驱动的xxx_open方法的代码--从而打开这个设备(操作这个设备)
    4. fops设备驱动系统调用之间的关系(讨论用户程序如何从用户空间到达驱动程序的)图2-4
      1. 四层模型:用户空间--系统调用--VFS虚拟文件系统--设备驱动(在fops找到对应的cdev)
  5. 设备编号,结构体dev_t,高12位为主设备号,低20位为次设备号;

>>> 创建一份虚拟的字符设备文件
设备驱动程序,驱动 初始化函数xxx_init(),编写思路:
  1. 设备号申请(主次、静动)
  2. 设备注册(分配一个udev设备结构体),注意这里udev泛指受udev管理的设备,可以是cdev字符设备
  3. 硬件资源的初始化(根据驱动程序的设备资源而言)
  4. 设备驱动的操作方法(fops结构体填充、ioctl命令构造)
  5. 设备初始化(关联设备和fops)
  6. 将设备添加到系统(加入系统设备树当中)
  7. 创建设备”类“(设备class,交由udev管理,同时会在sysfs创建“类”目录)
  8. 将上述设备,加入到设备“类”当中(在sysfs系统中创建设备节点)

设备驱动程序,驱动 退出函数xxx_exit(),编写思路:
  1. 删除udev设备驱动结构
  2. 释放设备号
  3. 删除sysfs中的设备节点
  4. 删除sysfs中的设备“类”

>>> sysfs文件系统,获取:

>>> proc文件系统,获取:

>>> udev自动设备管理,获取:
  1. udev的工作内容:根据sysfs中的设备信息,在/dev下动态创建设备文件


高级内容,需要简化,暂时未计划修改

>>>混合设备驱动,获取:
  1. 混合设备(简化字符驱动编写,头文件 <linux/miscdevice.h>,设备结构体 struct miscdevice)
  2. 混合设备驱动框架(程序清单2.27,misc没有主设备号)


>>>linux设备驱动模型,获取:(这部分有点大,个人感觉只能熟悉一下概念)
  1. 设备管理模型(头文件 <linux/device.h>,关键结构体 struct device,一般被嵌入到子系统里面)
备注:
  1. 2017/2/25 21:21,第一次看,当真不明白
  2. 2017/2/26 16:16,第二次看,其实这是非常容易移植且稳健的方式


>>>平台设备和驱动,获取:
  1. 平台驱动与普通驱动的区别(图2.8对比,platform方式编程,资源与驱动分离,便于移植)
  2. 平台驱动示例(程序清单2.40和2.41,一个是平台设备驱动,一个是该平台下的某个设备驱动)
  3. 测试用例(需要加载两个ko,一个平台,一个该平台下的子驱动)


高级疑问释放

>>>平台机制,获取:




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值