linux-块设备简单总结
文章目录
- 前言
- 一、什么是块设备?
- 二、使用梳理
- 1.使用请求队列
- 1.1 初始化
- 1.2 队列请求处理函数
- 2.不使用请求队列
- 2.1 初始化
- 2.2 制造请求函数
- 运行验证
前言
@和原子哥一起学习Linux
开发环境:I.MX6Ull开发板
参考书籍:
《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.6.pdf》
《linux设备驱动开发详解-基于最新的linux4.0内核》
个人学习笔记,欢迎讨论
一、什么是块设备?
块设备驱动其实就是存储设备驱动,块设备只能以块为单位进行读写访问。
二、使用梳理
linux 内核使用 gendisk 来描述一个磁盘设备, 使用request_queue、 request 和 bio去读写数据,每个磁盘(gendisk)都要分配一个 request_queue。
内核将对块设备的读写都发送到请求队列 request_queue 中, request_queue 中是大量的request(请求结构体),而 request 又包含了 bio, bio 保存了读写相关数据。
对于机械硬盘而言,将那些杂乱的访问按照一定的顺序进行排列可以有效提高磁盘性能, linux 里面针对不同的存储设备实现了不同的 I/O 调度算法。
1)机械硬盘这样的存储设备,需要 I/O 调度器来优化数据读写过程,需要使用请求队列读写设备
2)对于 EMMC、 SD 卡这样的非机械设备,可以进行完全随机访问,所以就不需要复杂的 I/O 调度器,不需要请求队列
1.使用请求队列
1.1 初始化
省略错误 。。。
//申请内存ramdisk.ramdiskbuf = kzalloc(RAMDISK_SIZE, GFP_KERNEL);。。。//初始化自旋锁,后面用spin_lock_init(&ramdisk.lock);//注册块设备ramdisk.major = register_blkdev(0, RAMDISKNAME);。。。//申请设备gendisk,申请3个分区ramdisk.gendisk = alloc_disk(RAMDISK_MINOR);。。。//分配初始化请求队列ramdisk.queue = blk_init_queue(do_ramdisk_request, &ramdisk.lock);。。。//注册diskramdisk.gendisk->major = ramdisk.major;ramdisk.gendisk->first_minor = 0; //起始设备号ramdisk.gendisk->fops = &ramdisk_fops;ramdisk.gendisk->queue = ramdisk.queue;sprintf(ramdisk.gendisk->disk_name, RAMDISKNAME);//使用 set_capacity 函数设置本块设备容量大小set_capacity(ramdisk.gendisk, RAMDISK_SIZE/512);//将 gendisk 添加到内核中,也就是向内核添加一个磁盘设备。add_disk(ramdisk.gendisk);return 0;
1.2 队列请求处理函数
static void ramdisk_transfer(struct request *req)
{unsigned long start = blk_rq_pos(req) << 9; //扇区地址转字节地址unsigned long len = blk_rq_cur_bytes(req);//使用 bio_data 函数获取请求中 bio 保存的数据void *buffer = bio_data(req->bio);if (rq_data_dir(req) == READ)memcpy(buffer, (char *)ramdisk.ramdiskbuf + start, len);elsememcpy((char *)ramdisk.ramdiskbuf + start, buffer, len);
}static void do_ramdisk_request(struct request_queue *q)
{struct request *req;int err = 0;//循环处理队列req = blk_fetch_request(q);while (req != NULL) {ramdisk_transfer(req);//* 判断是否为最后一个请求,如果不是的话就获取下一个请求if (!__blk_end_request_cur(req, err))req = blk_fetch_request(q);}
}
2.不使用请求队列
2.1 初始化
省略错误 。。。
//申请内存ramdisk.ramdiskbuf = kzalloc(RAMDISK_SIZE, GFP_KERNEL);。。。//注册设备ramdisk.major = register_blkdev(0, RAMDISKNAME);。。。//申请设备gendisk,申请3个分区ramdisk.gendisk = alloc_disk(RAMDISK_MINOR);。。。
//分配初始化请求队列
ramdisk.queue = blk_alloc_queue(GFP_KERNEL);
。。。
//设置制造请求
blk_queue_make_request(ramdisk.queue, ramdisk_make_request_fn);
//注册diskramdisk.gendisk->major = ramdisk.major;ramdisk.gendisk->first_minor = 0; //起始设备号ramdisk.gendisk->fops = &ramdisk_fops;ramdisk.gendisk->queue = ramdisk.queue;sprintf(ramdisk.gendisk->disk_name, RAMDISKNAME);//使用 set_capacity 函数设置本块设备容量大小set_capacity(ramdisk.gendisk, RAMDISK_SIZE/512);//将 gendisk 添加到内核中,也就是向内核添加一个磁盘设备。add_disk(ramdisk.gendisk);return 0;
2.2 制造请求函数
static void ramdisk_make_request_fn(struct request_queue *q, struct bio *bio)
{int offset;struct bio_vec bvec;struct bvec_iter iter;unsigned long len = 0;offset = bio->bi_iter.bi_sector << 9; //获取设备偏移地址bio_for_each_segment(bvec, bio, iter) {char *ptr = page_address(bvec.bv_page) + bvec.bv_offset;len = bvec.bv_len;if (bio_data_dir(bio) == READ)memcpy(ptr, (char *)ramdisk.ramdiskbuf + offset, len);else if(bio_data_dir(bio) == WRITE) /* 写数据 */memcpy((char *)ramdisk.ramdiskbuf + offset, ptr, len);offset += len; }set_bit(BIO_UPTODATE, &bio->bi_flags);bio_endio(bio, 0);return;
}
运行验证
加载模块
fdisk -l //查看磁盘信息
mkfs.vfat /dev/ramdisk//格式化/dev/ramdisk
mount /dev/ramdisk /tmp//挂载后就可以访问了
linux-块设备简单总结相关推荐
- [转]linux 块设备驱动
转自 linux块设备IO栈 http://www.sysnote.org/2015/08/06/linux-io-stack/ linux块设备IO流程 驱动 https://www.cnblogs ...
- Linux块设备驱动总结
<Linux设备驱动程序>第十六章 块设备驱动程序读书笔记 简介 一个块设备驱动程序主要通过传输固定大小的随机数据来访问设备 Linux内核视块设备为与字符设备相异的基本设备类型 Linu ...
- [转]Linux块设备加速缓存bcache和dm-cache:使用SSD来加速服务器
dm-cache 与 bcache 在 LSFMM 2013 峰会上,Mike Snitzer, Kent Overstreet, Alasdair Kergon, 和 Darrick Wong 共同 ...
- Linux块设备驱动-MTD子系统
Linux块设备驱动 块设备驱动 块设备驱动的引入 1. 简单字符驱动程序思想 2. 块设备驱动程序思想 块设备驱动框架 1. 层次框架 2. 分析ll_rw_block 块设备驱动程序编写 1.分配 ...
- 有点意思!Linux 块设备处理模型,基础【簇、柱面、存储的计算】
http://blog.csdn.net/zplove003/article/details/7020557 簇:簇是指可分配的用来保存文件的最小磁盘空间,扇区是磁盘最小的物理存储单元,但由于操作系统 ...
- Linux块设备概念和列出块设备命令学习
Linux块设备 一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存放暂时的数据,待条件成熟后,从缓存一次性写入设备或者从设备一次性读到缓冲区.可以随机访问,块设备的访问位 ...
- linux块设备驱动(一)——块设备概念介绍
linux块设备驱动(一)--块设备概念介绍 本文来源于: 1. http://blog.csdn.net/jianchi88/article/details/7212370 2. http://bl ...
- linux 块设备驱动(二)——块设备数据结构
linux 块设备驱动(二)--块设备数据结构 本文来源于: 1. http://www.cnblogs.com/dyllove98/archive/2013/07/01/3165567.html 块 ...
- linux 块设备驱动 (三)块设备驱动开发
linux 块设备驱动 (三)块设备驱动开发 一: 块设备驱动注册与注销 块设备驱动中的第1个工作通常是注册它们自己到内核,完成这个任务的函数是 register_blkdev(),其原型为: int ...
- linux内存加速硬盘缓存,linux块设备加速缓存之bcache
linux块设备加速缓存之bcache 什么是bcache 转载请注明出处:http://blog.csdn.net/liumangxiong bcache是linux内核块层cache.它使用类似S ...
最新文章
- WritePrivateProfileString、GetPrivateProfileString 读写配置文件
- 楼燚(yì)航的blog URL
- java 项目初始化一个定时任务_elastic-job 分布式定时任务框架 在 SpringBoot 中如何使用(一)初始化任务并定时执行...
- Docker 部署ELK 日志分析
- 简单讨论火车票系统后面的架构设计
- MUI - 解决bug: iphone页面保存时popPicker自动弹出来
- Android开源框架Afinal第一篇——揭开圣女的面纱
- jquery基础选择器和层次选择器
- on_mouse OpenCV 获得矩形区域
- web访问linux创建目录权限设置,centos7下新建一个用户并限制访问目录
- hasChildNodes()
- ZIGBEE 工程内区分终端与协调器
- python可以开发软件_python可以开发软件吗
- 大陆人怎么去香港银行开户?
- Google 百度 图标收藏
- RX的使用一:RXjava初级入门
- msysgit+apache安装说明
- 汽车产业链SCP分析框架-湖北
- 武汉智慧工地管理系统能帮助建筑施工提升质量吗?
- “寻梦之路 阿里之行”北城大数据学院学生代表团赴北京阿里中心参观...
热门文章
- AI一分钟|快播王欣出狱,与姚劲波、何小鹏一起畅谈人工智能、区块链
- 重庆-新加坡国际电竞嘉年华落幕“文旅+”助推建设国际旅游目的地
- 20131012-Actel公司申请License的方法
- 基于单片机的车内滞留儿童预警系统设计
- 怎样测量地图上曲线的长度_怎样从地图上估算出一条铁路的长度?找一张地图,计算从北京到广州铁路线的长度。...
- Hadoop实战问题记录
- C++ L1-034. 点赞
- NLP系列——(7)卷积神经网络
- 无忧考吧java的题库准吗,无忧考吧题库_无忧考吧从业题库难度和真正考试难度一样吗_淘题吧...
- 专访趋势科技:全面解析APT攻击过程