linux 块设备驱动(二)——块设备数据结构
本文来源于:
1. http://www.cnblogs.com/dyllove98/archive/2013/07/01/3165567.html
块设备相关的数据结构以及接口:
块设备接口则相对复杂,读写API没有直接到块设备层,而是直接到文件系统层,然后再由文件系统层发起读写请求。
一: block_device: 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);//添加分区
三: block_device_operations结构是块设备对应的操作接口,是连接抽象的块设备操作与具体块设备操作之间的枢纽。
struct block_device_operations {
int (*open) (struct inode *, struct file *);
int (*release) (struct inode *, struct file *);
int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned, unsigned long);
long (*compat_ioctl) (struct file *, unsigned, unsigned long);
int (*direct_access) (struct block_device *, sector_t, unsigned long *);
int (*media_changed) (struct gendisk *);
int (*revalidate_disk) (struct gendisk *);
int (*getgeo)(struct block_device *, struct hd_geometry *);
struct module *owner;
};
block_device_operations并不能完全提供文件操作全部的API,实际上只提供了open、release等函数,其他的文件操作依赖于def_blk_fops:
const struct file_operations def_blk_fops = {
.open = blkdev_open,
.release = blkdev_close,
.llseek = block_llseek,
.read = do_sync_read,
.write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write= generic_file_aio_write_nolock,
.mmap = generic_file_mmap,
.fsync = block_fsync,
.unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_blkdev_ioctl,
#endif
.splice_read = generic_file_splice_read,
.splice_write = generic_file_splice_write,
};
四: 系统对块设备进行读写操作时,通过块设备通用的读写操作函数将一个请求保存在该设备的操作请求队列(request queue)中,然后调用这个块设备的底层处理函数,对请求队列中的操作请求进行逐一执行。request_queue结构描述了块设备的请求队列,该结构定义如下:
struct request_queue
{
struct list_head queue_head;
struct request *last_merge;
elevator_t elevator;
/*请求队列列表*/
struct request_list rq;
request_fn_proc *request_fn;
merge_request_fn *back_merge_fn;
merge_request_fn *front_merge_fn;
merge_requests_fn *merge_requests_fn;
make_request_fn *make_request_fn;
prep_rq_fn *prep_rq_fn;
unplug_fn *unplug_fn;
merge_bvec_fn *merge_bvec_fn;
activity_fn *activity_fn;
/*自动卸载状态*/
struct timer_list unplug_timer;
int unplug_thresh;
unsigned long unplug_delay; /*自动卸载延时*/
struct work_struct unplug_work;
struct backing_dev_info backing_dev_info;
void *queuedata;
void *activity_data;
unsigned long bounce_pfn;
int bounce_gfp;
unsigned long queue_flags;//各种队列标志
/*保护队列结构,避免重入*/
spinlock_t *queue_lock;
/* 请求的核心结构*/
struct kobject kobj;
/*请求的配置*/
unsigned long nr_requests; /* 请求的最大数*/
unsigned int nr_congestion_on;
unsigned int nr_congestion_off;
unsigned short max_sectors;
unsigned short max_phys_segments;
unsigned short max_hw_segments;
unsigned short hardsect_size;
unsigned int max_segment_size;
unsigned long seg_boundary_mask;
unsigned int dma_alignment;
struct blk_queue_tag *queue_tags;
atomic_t refcnt;
unsigned int in_flight;
/*sg 参数配置*/
unsigned int sg_timeout;
unsigned int sg_reserved_size;
};
请求队列相关的处理函数包括:
//创建队列时提供了一个自旋锁。
request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock);
//获得队列中第一个未完成的请求。
struct request *elv_next_request(request_queue_t *q);
void end_request(struct request *req, int uptodate);//请求完成
void blk_stop_queue(request_queue_t *queue); //停止请求
void blk_start_queue(request_queue_t *queue); //开始请求
void blk_cleanup_queue(request_queue_t *);//清除请求队列
五:向内核注册和注销一个块设备可使用如下函数:
int register_blkdev(unsigned int major, const char *name);
int unregister_blkdev(unsigned int major, const char *name);
linux 块设备驱动(二)——块设备数据结构的更多相关文章
- 【转】深入浅出:Linux设备驱动之字符设备驱动
深入浅出:Linux设备驱动之字符设备驱动 一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据 ...
- Linux 设备驱动开发 —— platform设备驱动应用实例解析
前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 —— platform 设备驱动 ,下面将通过一个实例来深入我们的学习. 一.platform 驱动的工作过程 platfor ...
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
转载自:http://www.kancloud.cn/yueqian_scut/emlinux/106829 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sy ...
- [kernel]字符设备驱动、平台设备驱动、设备驱动模型、sysfs几者之间的比较和关联
转自:http://www.2cto.com/kf/201510/444943.html Linux驱动开发经验总结,绝对干货! 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动 ...
- Linux块设备驱动(二) _MTD驱动及其用户空间编程
MTD(Memory Technology Device)即常说的Flash等使用存储芯片的存储设备,MTD子系统对应的是块设备驱动框架中的设备驱动层,可以说,MTD就是针对Flash设备设计的标准化 ...
- 乾坤合一~Linux设备驱动之块设备驱动
1. 题外话 在蜕变成蝶的一系列学习当中,我们已经掌握了大部分Linux驱动的知识,在乾坤合一的分享当中,以综合实例为主要讲解,在一个月的蜕茧成蝶的学习探索当中,觉得数据结构,指针,链表等等占据了代码 ...
- 深入浅出:Linux设备驱动之字符设备驱
一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流 ...
- 蜕变成蝶~Linux设备驱动之字符设备驱动
一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流 ...
- 深入浅出:Linux设备驱动之字符设备驱动
一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流 ...
- Linux 设备驱动之字符设备
参考转载博客:http://blog.chinaunix.net/uid-26833883-id-4369060.html https://www.cnblogs.com/xiaojiang1025/ ...
随机推荐
- 刷题总结——生产产品(vijo1243)
题目: 描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器中的任何一台完成,但生 ...
- jenkins下添加HTML Publisher Plugin及配置
1.点击“系统设置”->“插件管理”,点击可选插件,搜索插件,如下: 2.点击直接安装,等待安装完成,如下: 3.在配置job中,在构建后操作,选择安装的HTML Publisher plugi ...
- 【python接口自动化】logger
#! /usr/bin/env python # coding=GBK import logging, os class Logger: def __init__(self, path, clevel ...
- Manjaro中源码安装gcc7.1
刚刚gcc 7.1也出来了,想在使用熟悉的linux下试试,特记录如下: 准备必要的系统环境:(升级系统到最新,安装必要的工具) pacman -Syyu ...
- 我的logging 配置
#encoding=utf-8 import logging.config logging.config.dictConfig({ 'version': 1, 'disable_existing_lo ...
- http协议相关面试题
浏览器输入url按回车背后经历了哪些? 1.在PC浏览器的地址栏输入一串URL,然后按Enter键这个页面渲染出来,这个过程中都发生了什么事? 1.首先,在浏览器地址栏中输入url,先解析url,检测 ...
- serializeObject 的应用
function sendForm() { var invOrderModelWrapper = {}; // 头 var objHeader = $('#invOrderForm').seriali ...
- UPC 2219: A^X mod P
题形:另类快速幂 题意: f(x) = K, x = 1 f(x) = (a*f(x-1) + b)%m , x > 1 Now, Your task is to calculate ( A^( ...
- JSONP简单示例
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"><head> < ...
- Codeforces 875C National Property(拓扑排序)
题目链接 National Property 给定n个单词,字符集为m 现在我们可以把其中某些字母变成大写的.大写字母字典序大于小写字母. 问是否存在一种方案使得给定的n个单词字典序不下降. 首先判 ...