参考内核自带的块设备驱动程序:
drivers/block /xd.c
drivers/block /z2ram.c
1.本节需要的结构体如下:
1.1 gendisk磁盘结构体:
struct gendisk { int major; //设备主设备号,等于register_blkdev()函数里的major int first_minor; //起始次设备号,等于0,则表示此设备号从0开始的 int minors; //分区(次设备)数量,当使用alloc_disk()时,就会自动设置该成员 char disk_name[32]; //块设备名称, 等于register_blkdev()函数里的name struct hd_struct **part; /*分区表的信息*/ int part_uevent_suppress; struct block_device_operations *fops; //块设备操作函数 struct request_queue *queue; //请求队列,用于管理该设备IO请求队列的指针* void *private_data; /*私有数据*/ sector_t capacity; /*扇区数,512字节为1个扇区,描述设备容量*/ .... };
1.2 request申请结构体:
struct request { //用于挂在请求队列链表的节点,使用函数elv_next_request()访问它,而不能直接访问 struct list_head queuelist; struct list_head donelist; /*用于挂在已完成请求链表的节点*/ struct request_queue *q; /*指向请求队列*/ unsigned int cmd_flags; /*命令标识*/ enum rq_cmd_type_bits cmd_type; //读写命令标志,为 0(READ)表示读, 为1(WRITE)表示写 sector_t sector; //要提交的下一个扇区偏移位置(offset) ... ... unsigned int current_nr_sectors; //当前需要传送的扇区数(长度) ... ... char *buffer; //当前请求队列链表的申请里面的数据,用来读写扇区数据(源地址) ... ... };
2.本节需要的函数如下:
int register_blkdev(unsigned int major, const char *name);
创建一个块设备,当major==0时,表示动态创建,创建成功会返回一个主设备号