我目前正在尝试实现一个(不是那个?)简单的内核块设备驱动程序。
我的灵感主要来自《Linux Device Drivers, 3rd Edition 》一书,该书已于 2005 年出版,不再完全是最新的。
无论如何,逻辑仍然存在,我从中学到了很多。然而,示例并不是真正有效,因为自 2005 年以来许多事情都发生了变化。
我找到了一个github 存储库,其中应更新示例以适用于最近的内核,但我认为仍有一些内容需要更新,因为我无法调整示例以使其适用于内核 4.9.0
这是我的模块的制作方法:
初始化时:
- 将模块注册为块设备
register_blkdev
- 分配设备数据缓冲区
- 初始化自旋锁
- 初始化请求队列
- 配置请求队列
- 分配
gendisk
结构 - 填充
gendisk
结构 - 创建磁盘
add_disk
然后我实现了一个函数来处理来自请求队列的请求事件并处理块设备上的读写事件。
这是函数:(它受到 LLD-3rd 的高度启发,并进行了一些修改以匹配当前的内核函数)
static void block_mod_request(struct request_queue *queue)
{
printk(KERN_NOTICE "Entering request function\n");
struct request *request;
while(NULL != (request = blk_fetch_request(queue)))
{
blk_mod_t *self = request->rq_disk->private_data;
// Check if request is a filesystem request (i.e. moves block of data)
if(REQ_TYPE_FS != request->cmd_type)
{
// Close request with unsuccessful status
printk(KERN_WARNING "Skip non-fs request\n");
__blk_end_request_cur(request, -EIO);
continue;
}
// Treat request
block_mod_transfer(self, blk_rq_pos(request), blk_rq_cur_sectors(request), request->buffer, rq_data_dir(request));
// Close request with successful status
__blk_end_request_cur(request, 0);
}
return;
}
但是在编译时出现以下错误:
block_mod.c:82:91: error: ‘struct request’ has no member named ‘buffer’
block_mod_transfer(self, blk_rq_pos(request), blk_rq_cur_sectors(request), request->buffer, rq_data_dir(request));
将文件检blkdev.h
入内核 v4.9.0 标头后,该字段似乎buffer
不再存在于struct request
.
但是,我无法找到有关事物如何演变以及如何修改代码以使其工作的任何信息。
如果我理解得很好,该buffer
字段应该是指向虚拟内核地址的指针。我想一旦这个缓冲区被填充/读取,内核就会处理与用户空间之间的数据传输。
我有点迷茫,因为如果请求不再提供内核虚拟地址,我找不到应该在哪里找到内核虚拟地址。
我怎么知道在哪里传输数据?