I'm currently trying to implement a (not that ?) simple kernel block device driver.
I inspired mainly from the book Linux Device Drivers, 3rd Edition which is not totally up-to-date anymore as it was published in 2005.
Anyway the logic is still there and I learnt a lot from it. However examples are not really effective as many things have changed since 2005.
I found a github repository where examples should be updated to work on recent kernels but I think there is still some things to update as I can't adapt examples to make it work on kernel 4.9.0
Here is how my module is made:
At initialization :
- Register the module as block device with
register_blkdev
- Allocate the device data buffer
- Initialize spinlock
- Initialize request queue
- Configure request queue
- Allocate
gendisk
structure - Fill
gendisk
structure - Create the disk with
add_disk
Then I implemented a function to handle request events from request queue and treat read and write events on the block device.
Here is the function : (It's highly inspired from LLD-3rd with some modifications to match current kernel functions)
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;
}
However at compiling I got the following error:
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));
After checking file blkdev.h
into kernel v4.9.0 headers, it seems that the field buffer
no longer exists into struct request
.
However I'm not able to find any information on how things have evolved and how to modify the code to make it work.
If I understand well, the buffer
field is supposed to be a pointer to a virtual kernel address. I suppose that once this buffer filled/read the kernel handles the transfer of data to/from userspace.
I'm kinda lost because I can't find where I should find the kernel virtual address if it's not given by the request anymore.
How am I supposed to know where to transfert data?