您的当前位置:首页正文

Linux块设备驱动架构分析

2024-11-30 来源:个人技术集锦

Linux驱动开发之块设备



前言

块设备概念:块设备是指只能以块为单位进行访问的设备,块的大小一般是512个字节的整数倍。常见的块设备包括硬盘、SD卡、光盘等。


一、块设备驱动的系统架构

1.VFS

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

1.1.Cache

当用户发起文件访问请求的时候,首先回到Disk Cache中寻址文件是否被缓存了,如果在Cache,则直接从cache中读取。如果数据不在缓存中,就必须要到具体的文件系统中读取数据了。

1.2.Mapping Layer

首先确定文件系统的block size,然后计算所请求的数据包含多少个block。

1.3.Generic Block Layer

Linux内核把块设备看做是由若干个扇区组成的数据空间,上层的读写请求在通用块层被构造成一个或多个bio结构。

1.4.I/O Scheduler Layer

I/O调度层负责采用某种算法(如:电梯调度算法)将I/O操作进行排序。

电梯调度算法的基本原则:如果电梯现在朝上运动,如果当前楼层的上方和下方都有请求,则先响应所有上方的请求,然后才向下响应下方的请求;如果电梯向下运动,则刚好相反。

1.5.Block Device Driver

在块系统架构的最底层,由块设备驱动根据排序好的请求,对硬件进行数据访问。


二、块设备驱动流程分析

初始化

  • 注册块设备驱动程序——register_blkdev
  • 初始化请求队列——blk_init_queue
  • 指明扇区大小——blk_queue_logical_block_size
  • 为块设备分配gendisk结构——alloc_disk
  • 初始化gendisk结构
    • major
    • first_minor
    • fops
    • queue
    • private_data
    • disk_name
    • 扇区数——set_capacity
  • 注册块设备——add_disk

实现读写请求函数

  • 取出一个要处理的请求——blk_fetch_request
  • 根据请求里的信息访问硬件,获取数据
  • 利用__blk_end_request_curl判断请求队列里是否还有剩余的请求要处理,如果有按照上面两步来处理

三、一个最简单的块设备驱动程序

1.源码

#include<linux/module.h>
#include<linux/init.h>
#include<linux/blkdev.h>
#include<linux/bio.h>

#include <linux/sched.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/timer.h>
#include <linux/types.h> /* size_t */
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/hdreg.h> /* HDIO_GETGEO */
#include 
显示全文