前言
工作需要,开始接触驱动开发了。
驱动作为硬件和软件的中间层,驱动就是驱使硬件设备行动的简述。驱动与底层的硬件打交道,根据硬件的工作方式,读写寄存器,完成设备的控制。驱动向上提供统一的API,使得软件可以使用通用的接口,通过不同的驱动来控制不同的设备。
驱动
驱动根据是否有操作系统,分为无操作系统的驱动和有操作系统的驱动。在无操作系统的情况下,驱动的接口由驱动工程师自定义,暴露自定义的接口。在有操作系统的情况下,驱动的结构由操作系统定义,驱动工程师需要根据架构设计驱动,把驱动整合到操作系统的内核中。
操作系统为一类设备定义一套接口,相同类别的设备使用相同的方式编写驱动。可以看出,在有操作系统的情况下,驱动编写比较复杂,需要符合操作系统的架构。但是,通过操作系统的控制,我们可以享受到操作系统提供的一系列功能支持,比如多任务多并发、内存管理机制。而且,在操作系统的控制下,上层应用可以更方便的控制设备。
驱动分类
根据设备类型分为字符设备、块设备和网络设备。
- 字符设备:指那些必须以串行顺序依次进行访问的设备,如触摸屏、磁带驱动器、鼠标等
- 块设备: 备可以按任意顺序进行访问,以块为单位进行操作,如硬盘、eMMC 等
- 网络设备: 面向数据包的接收和发送而设计,它并不倾向于对应于文件系统的节点。
网络设备是基于套接字API控制,字符设备和块设备基于文件系统来控制。
驱动开发
一般情况下,在Linux系统下,驱动作为内核的子模块,可以静态编译到内核中,也可以动态加载/卸载。具体实现时,只需要在Makefile定义目标文件时区分一下就可以了。
- obj-y 表示对应的文件要编译链接到内核中。
- obj-m 表示文件要作为模块编译。
- obj-n 表示目标文件不会被编译。
通过内核编译的配置,会生成不同的makefile,然后编译的时候会根据上述规则进行编译。
除了具有 obj- 形式的目标以外,还有 lib-y library 库、hostprogs-y 主机程序等目标,但是这两类基本都应用在特定的目录和场合下。
模块编译采用模块名加 -y 或 -objs 后缀的形式来定义模块的组成文件。
1 |
|
模块的名字为 ext2,由 balloc.o、dir.o、file.o 等多个目标文件最终链接生成 ext2.o 直至
ext2.ko 文件,并且是否包括 xattr.o、acl.o 等则取决于内核配置文件的配置情况,例如,如果
CONFIG_ EXT2_FS_POSIX_ACL 被选择,则编译 acl.c 得到 acl.o 并最终链接进 ext2。
内核模块
模块本身不会被编译进内核,可以控制内核的大小。模块一旦被加载,它就和其他部分是一样的。下面是一个最简单的模块编码:
1 |
|
内核模块包括几个部分:
- 加载函数, 使用insmod或者modprobe命令时,会执行加载函数,完成模块的初始化
- 卸载函数,使用rmmod命令时,会执行卸载函数,完成模块的卸载工作
- 模块许可证, 定义模块的许可证权限, 基本上使用GPL许可与
- 模块参数, 可以通过模块参数控制模块内部的全局变量的值, 可选
- 模块导出符号,导出的符号可以被其他模块使用,可选, 可以在/proc/kallsyms文件里看到符号
- 模块作者等信息
这是一个最简单的模块,两个文件放到同一个目录下,然后make就可以生成目标文件hello.ko。
内核模块的安装卸载命令如下:
1 | lsmod # 查看内核模块信息 |
printk输出的信息,可以使用dmesg命令查看。
1 |
|
更多
开始学习驱动开发了,其实没什么困难的,驱动发展到现在,和其他所有领域一样,都有了一套完整的体系。剩下的就是花时间去学习了。
本周五的时候,小组开了一个会议,主要就是对我之前开发的一个程序进行设计评审吧,也算是一个找茬的会议。做软件的都是这样,当你完成一个功能之后,然后再给客户看的时候,他们就会产生各种新的想法。即使前面已经再三确认了需求,但是在功能完成之后,他们肯定会提出新的要求,甚至否认之前已经达成的共识。这个跟项目管理的关系是比较大的,任务没有跟踪,需求没有文档化。到最后,领导说什么就是什么了,呵呵。
软件开发就是一个不断迭代的过程,需求不断的变化,功能也需要不断地完善。这个都是无可厚非的。
但是,在这个小组内,就有一个比较奇怪的现象。就是希望一切都能够一步到位,在软件设计的阶段就希望把很多东西做的完美。希望一切都可以抽象化, 过程通用化,统一化。比较难接收的就是要求一次实现之后不能改动了。在这个方面,一时之间还是有点儿难以适应,不敢苟同。在过往做过的这么多项目中,项目都是迭代演进的,需求也是按紧急程度分批实现的。罗马不是一天就建成的。软件开发,也是尽量往简单, 易扩展性来开发,毕竟软件开发不是一锤子买卖,是需要长久发展演化,不断进行完善的。老是抱着古老的瀑布开发模式来管理项目,的确是有点儿不与时俱进的,关键也没按瀑布模式产生任务文档啊。
既来之,则安之,适应之,改变之。
加油!
行动,才不会被动!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。
博客地址: https://fishmwei.github.io
掘金主页: https://juejin.cn/user/2084329776486919