LDD3 study note 1
-v0.1 2016.12.25 Sherlock init
LDD3的第三章介绍了一个简单的字符设备,实现了read/write/open/release等回调函数。
网上有LDD3自带的源代码,为了方便查找,我把官方源代码放到了: https://github.com/wangzhou/ldd3.git
自己实现的代码(第三章的简易字符设备)放在了:https://github.com/wangzhou/scull.git
本文只是记录一下实现中遇到的需要注意的地方,适合驱动入门的读者。
1. 这是一个什么设备
这是一个内存模拟出来的设备,简单说就是一些内存区域。在用户态,可以对相应的设备
文件read/write,相应的结果是读写这些内存区域中的数据。
这些内存的区域按照下面的数据结构组成:
+-------+ +-------+ +-------+ +-------+ | 链表 +-------->+ +--------->+ +-------->+ | ....| | | | | | | |+---+---+ +-------+ +-------+ +-------+| ... +--------+ +-------------------------+ | 指针 +----->+ quantum(e.g. 4000) Byte |+--------+ +-------------------------+| +-----> ... +--------+ | | +--------+ ... +--------+ | | +--------+ | | +--------+
可以看到数据只是存在quantum的单元里的,其他的数据结构都是为了索引到这个结构。
这个数据结构的特点是,链表的长度是不固定的(quantum, 指针数组的大小是固定的), 这样
只要一直往这个设备里写数据,链表就不断的加长,同时不断的创建新的quantum, 把数据
存在里面。这个过程可以吃光系统里所有的内存。还有一个特点就是,设备一开始不会分配
quantum, 只有有数据需要写入,又没有quantum时才开始分配。所有分配的quantum在模块
卸载时释放掉。同时,设备的读写函数设计成如果一次读写的数据超过一个quantum的界限,
那么只读写当前一个quantum中的数据。
2. open/release/read/write的实现
open: 把scull_dev挂成struce file的数据,方便以后其他的操作找到设备
read/write: …
release: 关闭文件的时候要调用到, 对scull_dev不做处理。模块退出的时候, 释放设备对应的
内存, 这个操作应该是在exit函数里,不放到这里。
3. 调试宏
在代码中插入了一些断言的宏,方便调试。
4. 自动创建设备节点
LDD3源代码中是加了一个脚本创建设备节点,这里创建一个class, 然后在class里创建这个
字符设备对应的设备文件。模块加载时会自动在/dev下创建设备文件。