首页 > 代码库 > [linux驱动]linux块设备学习笔记(二)

[linux驱动]linux块设备学习笔记(二)

1,gendisk结构体
在linux内核中,使用gendisk结构体来表示一个实际的磁盘设备的抽象,结构体定义如下所示:

 

[cpp] view plaincopy技术分享技术分享
 
  1. struct gendisk {  
  2. int major; //主设备号  
  3. int first_minor;//次设备号  
  4. int minors;        //最大次设备数,如果不能分区则为1               
  5. char disk_name[DISK_NAME_LEN]; //设备名称,显示在/proc/partitions和sysfs中  
  6. struct disk_part_tbl *part_tbl;//表示容纳分区表  
  7. struct hd_struct part0;//表示一个分区  
  8. struct block_device_operations *fops;//指向块设备操作集合  
  9. struct request_queue *queue;//指向I/O请求队列  
  10. void *private_data;//可以指向磁盘任何私有数据  
  11. int flags;//一些标志  
  12. struct device *driverfs_dev;  // FIXME: remove  
  13. struct kobject *slave_dir;  
  14. sector_t  capacity  //以512字节表示一个扇区的时候,该驱动器包含的扇区数目  
  15. struct timer_rand_state *random;  
  16. atomic_t sync_io;  
  17. struct work_struct async_notify;  
  18. #ifdef  CONFIG_BLK_DEV_INTEGRITY  
  19. struct blk_integrity *integrity;  
  20. #endif  
  21. int node_id;  
  22.   
  23. };  



 

[cpp] view plaincopy技术分享技术分享
 
  1. <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">linux内核中提供了一组函数来操作gendisk,如下</span>  

1.分配gendisk
使用下面函数来分配gendisk
struct gendisk *alloc_disk(int minors);
minors参数是这个磁盘使用的次设备号的数量
2.增加gendisk
gendisk结构体被分配后,系统还不能使用这个磁盘,需要用如下函数来注册设备,使用这个函数之前要保证驱动程序初始化工作完成并响应磁盘请求之后
void add_disk(struct gendisk *disk);
3.释放gendisk
当不需要一个磁盘时,用如下函数来释放gendisk;
void del_gendisk(struct gendisk *gp);
4.gendisk的引用计算
通过下面两个函数可以用来操作gendisk的引用计算和释放这个引用
struct kobject *get_disk(struct gendisk *disk);
void put_disk(struct gendisk *disk);

如果一个磁盘分成了几个分区,那么其分区表保存在hd_struct结构的数组中,该数组的地址存在gendisk的part字段中

2,block_device结构体
每个块设备都是由struct block_device结构体表示的,struct block_device来表示一个逻辑块设备对象。

描述块设备的数据结构有两个,一个是struct block_device,用来描述一个块设备或者块设备的一个分区,是逻辑抽象,侧重和文件系统交互;另一个是struct gendisk,用来描述实际块设备的特性,侧重和块设备驱动程序的交互。对于一个包含多个分区的块设备,struct block_device结构有多个,而struct gendisk结构永远只有一个。

 

[cpp] view plaincopy技术分享技术分享
 
  1. struct block_device {    
  2.     dev_t          bd_dev;  /该设备(分区)的设备号/    
  3.     struct inode *    bd_inode / 指向该设备文件的inode/  
  4.     struct super_block *    bd_super;    
  5.     int        bd_openers;  /一个引用计数,记录了该块设备打开的次数,或者说有多少个进程打开了该设备  
  6.     struct mutex        bd_mutex;  /* open/close mutex */    
  7.     struct list_head    bd_inodes;    
  8.     void *          bd_holder;    
  9.     int        bd_holders;    
  10.     struct block_device *  bd_contains;  /如果该block_device描述的是一个分区,则该变量指向描述主块设备的block_device,反之,其指向本身/  
  11.     unsigned        bd_block_size;    
  12.     struct hd_struct *  bd_part;  /如果该block_device描述的是一个分区,则该变量指向分区的信息  
  13.     /* number of times partitions within this device have been opened. */    
  14.     unsigned        bd_part_count;    
  15.     int        bd_invalidated;    
  16.     struct gendisk *    bd_disk;  /指向描述整个设备的gendisk结构  
  17.     struct list_head    bd_list;    
  18.     unsigned long      bd_private;    
  19.     /* The counter of freeze processes */    
  20.     int        bd_fsfreeze_count;    
  21.     /* Mutex for freeze */    
  22.     struct mutex        bd_fsfreeze_mutex;    
  23. };   

 

 

3,struct hd_struct结构体

该结构体用来表示一个分区信息,该结构体中的start_sect nr_sects和partno分别表示当前分区的起始扇区,分区的大小即扇区的数量,以及分区的编号

[linux驱动]linux块设备学习笔记(二)