
linux块设备学习专栏
主要记录对Linux块设备学习的笔记
<( ̄︶ ̄)Okay.
<( ̄︶ ̄)↗[GO!]
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
不使用请求队列
请求队列会用到I/O调度器,适合机械硬盘这种存储设备;对于EMMC,SD。ramdisk这样没有机械结构的存储设备,我们可以直接访问任意一个扇区,因此可以不需要I/O调度器,也就不需要请求队列了,本实验就来学习一下如何使用"制造请求"的方法。重点分析一下两个实验不一样的地方:/* * @description : 驱动出口函数 * @param : 无 * @return : 无 */static int __init ramdisk_init(void){ ...... /*原创 2022-02-19 18:27:08 · 182 阅读 · 0 评论 -
使用请求队列实验
关于块设备架构就讲解这些,接下来我们使用开发板上的 RAM 模拟一段块设备,也就是ramdisk,然后编写块设备驱动。首先是传统的使用请求队列的时候,也就是针对机械硬盘的时候如何编写驱动。先分段分析一下驱动代码。1.重要的数据结构及宏定义#define RAMDISK_SIZE (2 * 1024 * 1024) //容量大小为2MB#define RAMDISK_NAME "ramdisk" //名字#define RAMDISK_MINOR 3 /原创 2022-02-16 15:08:58 · 648 阅读 · 0 评论 -
Linux MMC子系统
Linux MMC/SD存储卡是一种典型的块设备,他的实现位于driver/mmc。driver/mmc下又分为card,core,host这3个目录。card实际上跟Linux的块设备子系统对接,实现块设备驱动以及完成请求。但是具体的协议经过core层的接口,最终通过host完成传输。另外card目录除了实现标准的MMC/SD存储卡以外,该目录还包含了一些SDIO外设卡的驱动,如driver/mmc/card/sdio_uart.c。core目录除了给card提供接口外,实际上也定义好了host驱动的原创 2022-02-15 20:27:35 · 1121 阅读 · 0 评论 -
实例:vmem_disk的I/O请求处理
在vmem_disk驱动中,通过模块参数request_mode的方式来支持3种不同的请求处理模式,如下为vmem_disk设备驱动的请求处理代码。Handle an I/O request该函数完成真正的硬件I/O操作(对于本例子而言,就是一个memcpy)static void vmem_disk_transfer(struct vmem_disk_dev *dev,unsigned long sector,unsigned long nsect,char *buffer, int write)原创 2022-02-14 21:47:46 · 251 阅读 · 0 评论 -
实例:vmem_disk设备驱动的block_device_operations(3)
vmem_disk提供block_device_operations结构体中的getgeo()成员函数。如下给出了vmem_disk设备驱动的block_device_operations结构体定义及其成员函数的实现。static int vmem_disk_getgeo(struct block_device *bdev,struct hd_geometry *geo){ long size; struct vmem_disk_dev *dev = bdev->bd_disk->pri原创 2022-02-14 21:17:59 · 268 阅读 · 0 评论 -
实例:vmem_disk驱动-->vmem_disk驱动模块的加载与卸载(2)
支持"制造请求",“请求队列”,static void setup_device(struct vmem_disk_dev *dev,int which){ memset(dev,0,sizeof(struct vmem_disk_dev)); dev->size = NSECTORS*HARDSECT_SIZE; dev->data = vmalloc(dev->size); if(dev->data = NULL) { printk(KERN_NOTICE"vm原创 2022-02-13 21:08:48 · 259 阅读 · 0 评论 -
实例:vmem_disk驱动-->vmem_disk的硬件原理(1)
vmem_disk是一种模拟磁盘,其数据实际存储在RAM中。它使用通过vmalloc()分配出来的内存空间来模拟出一个磁盘,以块设备的方式来访问这篇内存。加载vmem_disk.ko后,在使用默认模块参数的情况下,系统会增加4个块设备节点:其中,mkfs.ext2/dev/vmem_diska命令的执行会回馈如下信息:它将/dev/vemem_diska格式化为EXT2文件系统,之后我们可以mount这个分区并在其中进行文件读写。...原创 2022-02-13 20:14:42 · 341 阅读 · 0 评论 -
7.块设备驱动的I/O请求处理(2)
不适用请求队列使用请求队列对于一个机械磁盘设备而言的确有助于提高系统的性能,但是对于RAMDISK、ZRAM(Compressed RAM Block Device)等完全可真正随机访问的设备而言,无法从高级的请求队列逻辑中获益。对于这些设备,块层支持“无队列”的操作模式,为使用这个模式,驱动必须提供一个“制造请求”函数,而不是一个请求处理函数,“制造请求`”函数的原型:static void xxx_make_request(struct request_queue *queue,struct bio原创 2022-02-13 20:03:55 · 328 阅读 · 0 评论 -
Linux工作队列-workqueue
Linux-workqueue讲解 1.workqueue是什么?workqueue是对内核线程封装的,用于处理各种工作项的一种处理方法,由于处理对象是用链表拼接一个个工作项,依次取出来处理,然后从链表中删除,就像一个队列排好队依次处理一样,所以也称工作队列。所谓封装可以简单理解一个中转站,一边指向"合适"的内核线程,一边接受你丢过来的工作项,用结构体workqueue_struct表示,而所谓的工作项也是个结构体–work_struct,里面有个成员指针,指向你最终要实现的函数。workqueue原创 2022-02-12 16:24:18 · 811 阅读 · 0 评论 -
7.块设备驱动的I/O请求处理(1)
1.使用请求队列块设备驱动在使用请求队列的场景下,会用blk_init_queue()初始化reqyest_queue,而函数的第一个参数就是请求处理函数的指针。request_queue会作为参数传递给我们在调用blk_init_queue()时指定的请求处理函数,块设备驱动请求处理函数的原型为:static void xxx_req(struct request_queue *q);这个函数不能由驱动自己调用,只有当内核认为是时候让驱动处理对设备的读写等操作时,他才调用这个函数。该函数的主要工作原创 2022-02-12 15:15:33 · 672 阅读 · 0 评论 -
6.Linux块设备驱动的初始化
1.块设备注册函数在块设备的注册和初始化阶段,与字符设备驱动类似,块设备驱动要注册他们自己到内核,申请设备号。int register_blkdev(unsigned int major,const char *name);major参数是块设备要使用的主设备号;name为设备名,他会在/proc/device中,如果major为0,内核会自动分配一个新的主设备号;register_blkdev()函数的返回值就是这个主设备号,返回一个复制,表明发生错误了。2.注销函数int unregis原创 2022-02-11 20:08:10 · 1192 阅读 · 0 评论 -
5.I/O调度器
Linux 2.6以后的内核包含4个I/O调度器,它们分别是NoopI/O调度器、Anticipatory I/O调度器、Deadline I/O调度器与CFQ I/O调度器。其中,Anticipatory I/O调度器算法已经在2010年从内核中去掉了。(1)Noop I/O调度器是一个简化的调度程序,该算法实现了一个简单FIFO队列,它只进行最基本的合并,比较适合基于Flash的存储器。(2)Anticipatory I/O调度器算法推迟I/O请求,以期能对它们进行排序,获得最高的效率。在每次处理完原创 2022-02-11 19:42:12 · 529 阅读 · 0 评论 -
4.bio、request和request_queue
通常一个bio对应上层传递给块层的I/O请求;每个bio结构体实例及其包含的bvec_iter、bio_vec结构体实例描述了该I/O请求的开始扇区、数据方向(读还是写),数据放入的页,其定义如代码清单13.3所示。struct bvec_iter{ sector_t bi_sector; unsigned int bi_size; unsigned int bi_idx; unsigned int bi_bvec_done;}struct bio{ struct bio *bi_ne原创 2022-02-11 19:36:00 · 1040 阅读 · 0 评论 -
3.gendisk结构体
在Linux内核中,使用gendisk(通用磁盘)结构体来表示一个独立的磁盘设备(或分区)。1.gendisk结构体major、first_minor和minors共同表征了磁盘的主、次设备号,同一个磁盘的各个分区共享一个主设备号,而此设备号则不同;fops为block_device_operations,即块设备操作集合;queue是内核用来管理这个块设备的I/O请求队列的指针;private_data可用于指向磁盘的任何私有数据;hd_struct成员表示一个分区; 而disk_part_原创 2022-02-10 21:05:58 · 1579 阅读 · 0 评论 -
2.block_device_operations结构体
在块设备驱动中,有一个类似于字符设备驱动中file_operations结构体的block_device_operations结构体,他是对块设备操作的集合。1.block_device_operations结构体2.打开和释放int (*open)(struct block_device *,fmode_t);void (*release)(struct gendisk *,fmode_t);3.I/O控制int (*ioctl)(struct block_device *,fomede_t原创 2022-02-10 20:44:30 · 1026 阅读 · 0 评论 -
1.块设备的I/O操作特点
1.块设备对于I/O请求有对应的缓冲区;2.对于存储设备而言,调整读写的顺序作用巨大,在读写连续的扇区的存储速度比分离的扇区更快,提高性能;3.可被随机访问4.在Linux中,我们通常通过磁盘文件系统EXT4,UBIFS等访问磁盘,但是原始块设备也有一种原始设备的访问方式,如/dev/sdb1等,所有的EXT4,UBIFS、原始块设备又都工作在VFS之下,而EXT,UBIFS,原始块设备之下又包含I/O调度层以进行排序和合并。5.I/O调度层的基本目的是将请求按照他们在对应块设备上的扇区号进行排原创 2022-02-10 20:19:03 · 526 阅读 · 0 评论