事实上,这些内容是在给 Android 写一个功能的时候接触到的。
1. 整体结构。驱动程序的发挥空间极大,按照最小实现的出发点的话,结构上只需利用脚手架(宏,或者一些预定义函数)向系统声明/注册一些必需品即可。例如,MODULE_AUTHOR
和 MODULE_LICENSE
这样的宏(它们是向最终的可执行文件的某个特定的节内放置只读信息),module_init
和 module_exit
这样的(看上去的)函数。这些东东的老巢在 moduleparam.h。
2. 数据访问。驱动程序运行在内核,但是往往要跟上面的应用层进行交互,也免不了需要有数据通讯。据说 Linux 的原则是“只要你来自内核,就对你表示信任”,不过对应用层的数据就没有这么宽松。所以提供了统一的数据交互函数 copy_from_user
和 copy_to_user
,以及简单的数据安全性验证函数 access_ok
等。网上有一些对前两个函数的分析,并罗列除了其他几个函数:
| access_ok | 检查用户空间内存指针的有效性 |
| get_user | 从用户空间获取一个简单变量 |
| put_user | 输入一个简单变量到用户空间 |
| clear_user | 清除用户空间中的一个块,或者将其归零 |
| copy_to_user | 将一个数据块从内核复制到用户空间 |
| copy_from_user | 将一个数据块从用户空间复制到内核 |
| strnlen_user | 获取内存空间中字符串缓冲区的大小 |
| strncpy_from_user | 从用户空间复制一个字符串到内核 |
由于大部分从时间上看恐怕已经过时,因而上述函数名称也仅供索引,真要用的时候再查不迟。有一篇时间较新的,地址在 https://blog.csdn.net/liuhangtiant/article/details/85227125。另有一篇早的可以参看,在这儿 https://blog.csdn.net/ce123_zhouwei/article/details/8454226。