1.4 块设备驱动程序
1.4.1 Linux块设备驱动程序原理(1)
顾名思义,块设备驱动程序就是支持以块的方式进行读写的设备。块设备和字符设备最大的区别在于读写数据的基本单元不同。块设备读写数据的基本单元为块,例如磁盘通常为一个sector,而字符设备的基本单元为字节。从实现角度来看,字符设备的实现比较简单,内核例程和用户态API一一对应,这种映射关系由字符设备的file_operations维护。块设备接口则相对复杂,读写API没有直接到块设备层,而是直接到文件系统层,然后再由文件系统层发起读写请求。
block_device结构代表了内核中的一个块设备。它可以表示整个磁盘或一个特定的分区。当这个结构代表一个分区时,它的bd_contains成员指向包含这个分区的设备,bd_part成员指向设备的分区结构。当这个结构代表一个块设备时,bd_disk成员指向设备的gendisk结构。struct block_device {
dev_t bd_dev;
struct inode * bd_inode; /*分区结点*/
int bd_openers;
struct semaphore bd_sem; /*打开/关闭锁*/
struct semaphore bd_mount_sem; /* 加载互斥锁*/
struct list_head bd_inodes;
void * bd_holder;
int bd_holders;
struct block_device * bd_contains;
unsigned bd_block_size;//分区块大小
struct hd_struct * bd_part;
unsigned bd_part_count;//打开次数
int bd_invalidated;
struct gendisk * bd_disk;
struct list_head bd_list;
struct backing_dev_info *bd_inode_backing_dev_info;
unsigned long bd_private;
};
gendisk是一个单独的磁盘驱动器的内核表示。内核还使用gendisk来表示分区。struct gendisk {
int major; //主设备号
int first_minor;
int minors; //最大的次设备号数量,如果设备不能分区,该值为1
char disk_name[32]; //主设备名
struct hd_struct **part; //分区信息,有minors个
struct block_device_operations *fops;//设备操作
struct request_queue *queue; //设备管理I/O请求
void *private_data;
sector_t capacity;
int flags;
char devfs_name[64];
int number;
struct device *driverfs_dev;
struct kobject kobj;
struct timer_rand_state *random;
int policy;
atomic_t sync_io;
unsigned long stamp, stamp_idle;
int in_flight;
#ifdef CONFIG_SMP
struct disk_stats *dkstats;
#else
struct disk_stats dkstats;
#endif
};
gendisk结构的操作函数包括以下几个:struct gendisk *alloc_disk(int minors); //分配磁盘
void add_disk(struct gendisk *disk); //增加磁盘信息
void unlink_gendisk(struct gendisk *disk) //删除磁盘信息
void delete_partition(struct gendisk *disk, int part); //删除分区
void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags);//添加分区
【责任编辑:book TEL:(010)68476606】
点赞 0