Linux驱动开发之块设备初入门

1、块设备
  块设备将数据按照固定块大小的块中,每个块的大小通常在512字节到32768字节之间,磁盘、SD卡都是常见的块设备。

2、字符设备和块设备的区别:
字符设备 块设备
----------------------------------------------
按字节访问   按块进行访问
只能按照数据流访问   随机访问
直接访问设备   挂在文件系统的方式访问

3、Linux块设备处理模型

|-------------------------------------------------------------|
|                          VFS                              |
|-------------------------------------------------------------|
|    |                                        |            |
|Disk Caches                                    |            |
|    |                                        |            |
|-------------------------------------------------------------|
|Disk Filesystem  |  Disk Filesystem  |  Block Device File    |
|-----------------                    -----------------------|
|                    Mapping Layer                          |
|-------------------------------------------------------------|
|                  Generic Block Layer                      |
|-------------------------------------------------------------|
|                  I/O Scheduler Layer                        |
|-------------------------------------------------------------|
|    Block Device Driver      |      Block Device Driver      |
|------------------------    |        --------------------  |
|      Hard Disk            |            Hard Disk          |
|------------------------------------------------------------—|

VFS:虚拟文件系统,VFS是对各种具体文件系统的一种封装,为用户程序提供访问文件的统一接口。

Disk Cache:当用户发起文件访问请求的时候,首先会到Disk Cache中寻找文件是否被缓存,如果缓存中有则在Cache中读取,如果数据没有被缓存,那就必须到文件系统中去读取。

Mapping Layer:
  1、首先确定文件系统的block size,然后计算所请求的数据包含多少个block,
  2、调用具体文件系统的函数来访问文件的inode,确定所请求数据在磁盘上面的逻辑地址。

Generic block layer:
  Linux内核为快设备抽象成了统一的模型,把块设备看做是若干个扇区组成的数据空间。来完成块设备的相关核心功能。

I/O scheduler layer:
  I/O调度层负责将I/O操作顺序,采用电梯算法。提高 I/O 调度器的效率也是影响整个系统对块设备上数据管理效率的一个方面。

Block Device Driver:
  快设备驱动程序,完成和硬件的具体交互,块设备相关数据结构

4、设备描述 gendisk结构体
  内核使用 gendisk 结构来表示一个独立的磁盘设备,内核还使用 gendisk 结构来表示分区,在此结构中,很多程序必须由驱动程序来进行初始化。该结构体定义<linux/genhd.h>中。

4.1、gendisk结构体解析
    struct gendisk {
        int major;                    /*设备主设备号*/
        int first_minor;            /*起始次设备号*/
        int minors;                    /*次设备号的数量,也称为分区数量,如果改值为1,表示无法分区*/
        char disk_name[32];            /*设备名称*/
        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个扇区,描述设备容量*/
        ....
    };

struct gendisk *alloc_disk(int minors)
    分配一个gendisk结构,minors为此设备好的个数 = 分区数+1

void del_gendisk(struct gendisk *disk)
    当不需要这个磁盘的时候,释放gendisk结构

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1113f82fc69a591afa0531884adb3059.html