这个是对CU上OstrichFly的“写一个块设备驱动“文章的读书笔记。
首先建立一个”常规”的块驱动程序:
为设备申请一块连续的内存,作为磁盘:
unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES]; /* 16*1024*1024 */
创建一个块设备:
struct gendisk *alloc_disk(int minors); /*minors是该磁盘使用的次设备号的数目*/
simp_blkdev_disk = alloc_disk(1);
初始化请求队列:
struct request_queue *blk_init_queue(request_fn_proc *, spinlock_t *);/*request_fn_proc是处理函数*/
simp_blkdev_queue = blk_init_queue(simp_blkdev_do_request,NULL);
块设备相关操作:
static struct block_device_operations simp_blkdev_fops={
.owner = THIS_MODULE,
};
初始化块设备参数:
strcpy(simp_blkdev_disk->disk_name,SIMP_BLKDEV_DISKNAME); /*设置设备名*/
simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR; /*主设备号*/
simp_blkdev_disk->first_minor = 0; /*第一个次设备号*/
simp_blkdev_disk->fops = &simp_blkdev_fops; /*块设备的相关操作*/
simp_blkdev_disk->queue = simp_blkdev_queue; /*上面的请求队列*/
set_capacity(simp_blkdev_disk,SIMP_BLKDEV_BYTES>>9);/*设置容量*/
然后向模块添加这个设备:
add_disk(simp_blkdev_disk);
不要忘了在模块退出函数中移除相关的结构:
del_gendisk(simp_blkdev_disk);
put_disk(simp_blkdev_disk);
blk_cleanup_queue(simp_blkdev_queue);
最后还有一个请求队列处理函数:
void simp_blkdev_do_request(struct request_queue*q)
这个函数对我们块设备(实质上是一块内存)的请求进行处理。但是后面会被改掉。
总结:
这是整个块驱动程序的框架,最关键的是对块设备gendisk结构参数的设置,包括一些操作函数和一个请求队列。
2016.04.10