struct gendisk
--169-->驱动的主设备号
--170-->第一个次设备号
--171-->次设备号的数量,即允许的最大分区的数量,1表示不允许分区
--174-->设备名称
--185-->分区表数组首地址
--186-->第一个分区,相当于part_tbl->part[0]
--188-->操作方法集指针
--189-->请求对象指针
--190-->私有数据指针
--193-->表示这是一个设备
gendisk是一个动态分配的结构体,所以不要自己手动来分配,而是使用内核相应的API来分配,其中会做一些初始化的工作
struct gendisk *alloc_disk(int minors); //注册gendisk类型对象到内核 void add_disk(struct gendisk *disk); //从内核注销gendisk对象 void del_gendisk(struct gendisk *gp);上面几个API是一个块设备驱动中必不可少的部分,下面的两个主要是用来内核对于设备管理用的,通常不要驱动来实现
//对gendisk的引用计数+1 struct kobject *get_disk(struct gendisk *disk); //对gendisk的引用计数-1 void put_disk(struct gendisk *disk);这两个API最终回调用kobject *get_disk() 和kobject_put()来实现对设备的引用计数
block_device_operations和字符设备一样,如果使用/dev接口访问块设备,最终就会回调这个操作方法集的注册函数
//include/linux/blkdev.h 1558 struct block_device_operations { 1559 int (*open) (struct block_device *, fmode_t); 1560 void (*release) (struct gendisk *, fmode_t); 1561 int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); 1562 int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); 1563 int (*direct_access) (struct block_device *, sector_t, 1564 void **, unsigned long *); 1565 unsigned int (*check_events) (struct gendisk *disk, 1566 unsigned int clearing); 1568 int (*media_changed) (struct gendisk *); 1569 void (*unlock_native_capacity) (struct gendisk *); 1570 int (*revalidate_disk) (struct gendisk *); 1571 int (*getgeo)(struct block_device *, struct hd_geometry *); 1573 void (*swap_slot_free_notify) (struct block_device *, unsigned long); 1574 struct module *owner; 1575 };struct block_device_operations
--1559-->当应用层打开一个块设备的时候被回调
--1560-->当应用层关闭一个块设备的时候被回调
--1562-->相当于file_operations里的compat_ioctl,不过块设备的ioctl包含大量的标准操作,所以在这个接口实现的操作很少
--1567-->在移动块设备中测试介质是否改变的方法,已经过时,同样的功能被check_event()实现
--1571-->即get geometry,获取驱动器的几何信息,获取到的信息会被填充在一个hd_geometry结构中
--1574-->模块所属,通常填THIS_MODULE
每一个gendisk对象都有一个request_queue对象,前文说过,块设备有两种访问接口,一种是/dev下,一种是通过文件系统,后者经过IO调度在这个gendisk->request_queue上增加请求,最终回调与request_queue绑定的处理函数,将这些请求向下变成具体的硬件操作
294 struct request_queue { 298 struct list_head queue_head; 300 struct elevator_queue *elevator; 472 };