在Linux内核中,使用gendisk
(通用磁盘)结构体来表示一个独立的磁盘设备(或分区)。
1.gendisk结构体
- major、first_minor和minors共同表征了磁盘的主、次设备号,
同一个磁盘的各个分区共享一个主设备号,而此设备号则不同
;
-
fops
为block_device_operations
,即块设备操作集合;
-
queue
是内核用来管理这个块设备的I/O请求队列的指针;
-
private_data
可用于指向磁盘的任何私有数据;
-
hd_struct
成员表示一个分区; 而disk_part_tbl
成员用来容纳分区表;part0和part_tbl两者的关系在于:
disk->part_tbl->part[0] = &disk->part0;
Linux内核提供了一组函数来操作gendisk,如下所示。
2.分配gendisk
gendisk
结构体是一个动态分配的结构体
,他需要特别的内核操作来初始化,驱动不能自己分配这个结构体,而应该使用下列的函数来分配。
struct gendisk *alloc_disk(int minors);
minors参数是这个磁盘使用的此设备号的数量,一般也就是磁盘分区的数量
,此后minors不能被修改。
3.增加gendisk
gendisk
结构体被分配后,系统还不能使用这个磁盘,需要调用如下函数来注册这个磁盘设备。
void add_disk(struct gendisk *disk);
特别要注意的是:对add_disk()
的调用必须发生在驱动程序的初始化工作完成并能响应磁盘的请求之后
。
4.gendisk引用计数
通过get_disk()
和put_disk()
函数可操作gendisk的引用计数,这个工作一般不需要驱动亲自做。
struct kobject *get_disk(struct gendisk *disk);
void put_disk(struct gendisk *disk);
前者最终会调用"kobject_get(&disk_to_dev(disk)->kobj);
"
后者则会调用"kobject_put(&disk_to_dev(disk)->kobj);
"