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
gendiskstructure - Fill
gendiskstructure - 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?