Linux中块设备驱动程序分析
基于《Linux设备驱动程序》书中的sbull程序以对Linux块设备驱动总结分析。
開始之前先来了解这个块设备中的核心数据结构:
struct sbull_dev {
int size; /* Device size in sectors */
u8 *data; /* The data array */
short users; /* How many users */
short media_change; /* Flag a media change? */
spinlock_t lock; /* For mutual exclusion */
struct request_queue *queue; /* The device request queue */
struct gendisk *gd; /* The gendisk structure */
struct timer_list timer; /* For simulated media changes */
};
在这个结构中,struct request_queue与 struct gendisk 是这个结构中的重要成员,
也是块设备中的重要结构,这个文章中的大部分阐述都是基于这两个结构的操作。
一.流程:
块设备驱动也是从init函数開始的,所以分析也从这里開始。
第一步:
register_blkdev(sbull_major, "sbull");
先注冊块设备,第一个參数是设备号,为0表完动态分配,第二个为设备名。
第二步:
Devices = kmalloc(ndevices*sizeof (struct sbull_dev), GFP_KERNEL);
创建这个块设备的核心数据结构,也就是这个块设备的对象实体,创建了ndevice这样
的实体。
第三步:
setup_device(Devices + i, i);
说白了,就是初始化实体,并把它加入到系统的block层中去。这个步骤非常重要,它完
成以下面一些操作:
1.初始化一个自旋锁。
spin_lock_init(&dev->lock);
2.分配一个请求队列,并用1中的自旋锁来控制对队列的訪问。
dev->queue = blk_init_queue(sbull_full_request, &dev->lock);
3.分配,初始化及安装对应的gendisk结构。
dev->gd = alloc_disk(SBULL_MINORS);
if (! dev->gd) {
printk (KERN_NOTICE "alloc_disk failure/n");
goto out_vfree;
}
dev->gd->major = sbull_major;
dev->gd->first_minor = which*SBULL_MINORS;
dev->gd->fops = &sbull_ops;
dev->gd->queue = dev->queue;
dev->gd->private_data = dev;
snprintf (dev->gd->disk_name, 32, "sbull%c", which + 'a');
set_capacity(dev->gd, nsectors*(hardsect_size/KERNEL_SECTOR_SIZE));
4.最后add_disk完毕整个初始化过程,这步一定要在初始化的最后再调用,由于
add_disk后,可能就会调用磁盘的操作函数,假设初始化还没有完毕就会出错。
二.块设备操作 struct block_device_operations 结构分析:
sbull模块中的该结构:
static struct block_device_operations sbull_ops = {
.owner = THIS_MODULE,
.open = sbull_open,
.release = sbull_release,
.media_changed = sbull_media_changed,
.revalidate_disk = sbull_revalidate,
.ioctl = sbull_ioctl
};
open与release这两个函数就不再详细分析,它们有一个重要功能就是添加用户计数和
降低用户计数。media_changed 和revalidata_disk即是对可移动介质的支持,像u盘等
等这些可移动,即插即用的设备就应该实现这两个函数。media_changed是检查介质是
否改变,发迹即返回非零,revalidate_disk即介质改变后运行。它们之间怎样联系我
们不用管,我们主要实现这个函数的实体就可以。
ioctl函数,ioctl函数的功能也简化了,可实际的磁盘设备大多也主要是实现对磁盘信
息的查询。
三.请求处理。
块设备驱动程序的核心是请求处理部分,是块设备驱动的难点。设计得好否直接关
系到设备的性能。
我们看在安装块设备实体的时候,初始化了一个请求队列:
dev->queue = blk_init_queue(sbull_full_request, &dev->lock);
这个操作就是把生成的请求队列dev->queue与请求函数sbull_full_request绑定在一
起。sbull中的request函数:
static void sbull_full_request(request_queue_t *q)
{
struct request *req;
int sectors_xferred;
struct sbull_dev *dev = q->queuedata;
while ((req = elv_next_request(q)) != NULL) {
if (! blk_fs_request(req)) {
printk (KERN_NOTICE "Skip non-fs request/n");
end_request(req, 0);
continue;
}
sectors_xferred = sbull_xfer_request(dev, req);
if (! end_that_request_first(req, 1, sectors_xferred)) {
blkdev_dequeue_request(req);
end_that_request_last(req);
}
}
}
req = elv_next_request(q) 获取队列中第一个未完毕的请求,两次调用而没有
执行end_that_request_last或者end_request时得到的是同样的结果,由于它不会删除
队列中的请求。仅仅有结束该请求,才会得到下一个请求。sbull_xfer_request在这里即
是实际的传输数据。
一个实际的块设备请求处理要这些要复杂得多,那就要更深入了解request结构,bio结
构,队列结构等等。但在这里先不深入去讨论。
Linux中块设备驱动程序分析的更多相关文章
- LINUX中块设备文件和字符设备文件的本质区别
在LINUX系统文件类型分类的文章中我们提到了 块设备 和 字符设备文件,那么什么是块设备 字符设备文件呢?他们之间有什么本质上的区别呢? 设备文件分为 Block(块) Device Driver ...
- 嵌入式驱动开发之--- 虚拟磁盘SBULL块设备驱动程序分析
#define SBULL_MINORS 16 /* 每个sbull设备所支持的次设备号的数量 */ #define KERNEL_SECTOR_SIZE 512 // 本地定 ...
- [中英对照]User-Space Device Drivers in Linux: A First Look | 初识Linux用户态设备驱动程序
如对Linux用户态驱动程序开发有兴趣,请阅读本文,否则请飘过. User-Space Device Drivers in Linux: A First Look | 初识Linux用户态设备驱动程序 ...
- 嵌入式Linux驱动学习之路(二十一)字符设备驱动程序总结和块设备驱动程序的引入
字符设备驱动程序 应用程序是调用C库中的open read write等函数.而为了操作硬件,所以引入了驱动模块. 构建一个简单的驱动,有一下步骤. 1. 创建file_operations 2. 申 ...
- 简单linux块设备驱动程序
本文代码参考<LINUX设备驱动程序>第十六章 块设备驱动程序 本文中的“块设备”是一段大小为PAGE_SIZE的内存空间(两个扇区,每个扇区512字节) 功能:向块设备中输入内容,从块设 ...
- 《Linux Device Drivers》第十六章 块设备驱动程序——note
基本介绍 块设备驱动程序通过主传动固定大小数据的随机访问设备 Linux核心Visual块设备作为基本设备和不同的字符设备类型 Linux块设备驱动程序接口,使块设备最大限度地发挥其效用.一个问题 一 ...
- 深入理解Linux内核-块设备驱动程序
扇区: 1.硬盘控制器将磁盘看成一大组扇区2.扇区就是一组相邻字节3.扇区按照惯例大小设置位512字节4.存放在块设备中的数据是通过它们在磁盘上的位置来标识,即首个扇区的下标和扇区的数目.5.扇区是硬 ...
- (linux)块设备驱动程序
1.4.1 Linux块设备驱动程序原理(1) 顾名思义,块设备驱动程序就是支持以块的方式进行读写的设备.块设备和字符设备最大的区别在于读写数据的基本单元不同.块设备读写数据的基本单元为块,例如 ...
- linux系统下块设备驱动程序
顾名思义,块设备驱动程序就是支持以块的方式进行读写的设备.块设备和字符设备最大的区别在于读写数据的基本单元不同.块设备读写数据的基本单元为块,例 如磁盘通常为一个sector,而字符设备的基本单元为字 ...
随机推荐
- js之checkbox的代码全选/全不选,使用id获取元素,而不是name
每当有多个选项的时候,都会有一种想法是:全选,全不选,如果子选项有被选,父选项也得被选. 注意:这里是根据id来获取元素的,但是不能直接用getElementById,因为那只能返回一个,而不是集合. ...
- cp命令的实现
#include <unistd.h> #include <fcntl.h> #include <stdlib.h> #define BUFFERSIZE 4096 ...
- 《学习opencv》笔记——矩阵和图像处理——cvMinManLoc,cvMul,cvNot,cvNorm and cvNormalize
矩阵和图像的操作 (1)cvMinManLoc函数 其结构 void cvMinMaxLoc(//取出矩阵中最大最小值 const CvArr* arr,//目标矩阵 double* min_val, ...
- 免费APP在线測试工具以及其用法
免费APP漏洞安全检測工具:http://safe.ijiami.cn/ 漏洞分析是爱加密推出免费 APP 漏洞分析平台,服务包含一键对APK 进行签名数据信息採集.内部配置信息採集.市场渠道相关信息 ...
- 14.2.5.2 Clustered and Secondary Indexes
14.2.5.2 Clustered and Secondary Indexes : 每个InnoDB 表 有一个特别的索引称为clustered index 行数据存储的地方. 典型的,cluste ...
- 【从cocos2d-x学习设计模式】第一阶段:辛格尔顿
设计模式,它总结了前辈在许多方案重用代码.它是一个想法. 因为我们爱cocos2d-x,然后我们从去cocos2d-x在设计模式中,右一起学习!本篇解释未来辛格尔顿. 提cocos2d-x中间Dire ...
- hadoop源码下载地址
http://svn.apache.org/repos/asf/hadoop/common/branches/
- Bootstrap表格的使用
先定义前端table <table class="table table-striped table-bordered table-hover" id="expan ...
- linux时间方面的设置
例如以下一段代码能够借鉴: static void _sleep_response_timeout(modbus_t *ctx) { #ifdef _WIN32 /* usleep doesn't e ...
- NET MVC RazorEngine 解析模板生成静态页
ASP.NET MVC 解析模板生成静态页一(RazorEngine) 简述 Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项.在早期的MVC版本中默认使用的是 ...