块设备层分析3

块设备层保序操作分析 8.POSTFLUSH request的完成同5,6步,最后进入到blk_ordered_complete_seq(),blk_ordered_cur_seq(q)当前的步骤为QUEUE_ORDSEQ_DONE,整个保序过程完毕,调用__blk_end_request(q->orig_bar_rq)对原始保序请求做完成的回调.A:通用块层可以提交一个带保序标签(BIO_RW_BARRIER)的BIO到IO请求队列,块设备层可以保证在保序BIO之前提交的BIO都先于BIO执行且抵达存储介质; 阅读详情

以上均是IDE总线上设备的通用接口,直到do_request开始才执行特定设备的驱动,如CD,HD, floppy等IDE设备。我们来看一下ide-disk:

1、 首先是设备的初始化操作。

IDE设备接口

static ide_driver_t idedisk_driver = {

       .gen_driver = {

              .owner           = THIS_MODULE,

              .name             = "ide-disk",

              .bus        = &ide_bus_type,

       },

       .probe                   = ide_disk_probe,

       .remove                 = ide_disk_remove,

       .shutdown             = ide_device_shutdown,

       .version          = IDEDISK_VERSION,

       .media                   = ide_disk,

       .supports_dsc_overlap   = 0,

       .do_request            = ide_do_rw_disk,

       .end_request          = ide_end_request,

       .error                    = __ide_error,

       .abort                    = __ide_abort,

       .proc                     = idedisk_proc,

};

static struct block_device_operations idedisk_ops = {

       .owner           = THIS_MODULE,

       .open             = idedisk_open,

       .release    = idedisk_release,

       .ioctl              = idedisk_ioctl,

       .getgeo           = idedisk_getgeo,

       .media_changed     = idedisk_media_changed,

       .revalidate_disk= idedisk_revalidate_disk

};

//设备注册

static int __init idedisk_init(void)

{

       return driver_register(&idedisk_driver.gen_driver);

}

//这个probe函数是在设备注册时由驱动模型去执行

static int ide_disk_probe(ide_drive_t *drive)

{

       struct ide_disk_obj *idkp;

       struct gendisk *g;

       idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);

      

//分配一个gendisk结构

g = alloc_disk_node(1 << PARTN_BITS,

                     hwif_to_node(drive->hwif));

       ide_init_disk(g, drive);

       //用上面的结构注册设备

       ide_register_subdriver(drive, &idedisk_driver);

       kref_init(&idkp->kref);

       //一些初始化操作

       idkp->drive = drive;

       idkp->driver = &idedisk_driver;

       idkp->disk = g;

       g->private_data = &idkp->driver;

       drive->driver_data = idkp;

       idedisk_setup(drive);

       g->minors = 1 << PARTN_BITS;

       g->driverfs_dev = &drive->gendev;

       g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;

       set_capacity(g, idedisk_capacity(drive));

       g->fops = &idedisk_ops;

       add_disk(g); //插入设备,至此,该设备可用

       return 0;

}

2、 处理IDE总线发来的请求

由上可以看到,IDE总线驱动调用设备的do_request()去处理这个请求,我们在上面的注册中可以看到。在ide-disk里,它是ide_do_rw_disk():

/*

* 268435455 == 137439 MB or 28bit limit

* 320173056 == 163929 MB or 48bit addressing

* 1073741822 == 549756 MB or 48bit addressing fake drive

*/

static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)

{

       ide_hwif_t *hwif = HWIF(drive);

……

       if (hwif->rw_disk)

       hwif->rw_disk(drive, rq);

       return __ide_do_rw_disk(drive, rq, block);

}

//以下就是特定硬盘设备的驱动了,因为我们只关心块设备驱动编程的框架,所以就不深入进去了。

/*

* __ide_do_rw_disk() issues READ and WRITE commands to a disk,

* using LBA if supported, or CHS otherwise, to address sectors.

*/

static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block)

{

       ide_hwif_t *hwif    = HWIF(drive);

       unsigned int dma    = drive->using_dma;

       u8 lba48         = (drive->addressing == 1) ? 1 : 0;

       task_ioreg_t command   = WIN_NOP;

       ata_nsector_t         nsectors;

       nsectors.all            = (u16) rq->nr_sectors;

       if (hwif->no_lba48_dma && lba48 && dma) {

              if (block + rq->nr_sectors > 1ULL << 28)

                     dma = 0;

              else

                     lba48 = 0;

       }

       if (drive->select.b.lba) {

              if (lba48) {

                     ……

              } else {

              ……

              }

       } else {

              ……

       }

       if (dma) {

              ……

              /* fallback to PIO */

              ide_init_sg_cmd(drive, rq);

       }

       if (rq_data_dir(rq) == READ) {

              if (drive->mult_count) {

                     hwif->data_phase = TASKFILE_MULTI_IN;

                     command = lba48 ? WIN_MULTREAD_EXT : WIN_MULTREAD;

              } else {

                     hwif->data_phase = TASKFILE_IN;

                     command = lba48 ? WIN_READ_EXT : WIN_READ;

              }

              ide_execute_command(drive, command, &task_in_intr, WAIT_CMD, NULL);

              return ide_started;

       } else {

       ……

              return pre_task_out_intr(drive, rq);

       }

}

3、 块设备驱动小结

我们由上看到, 块设备驱动编程的主要工作包括分配并初始化一个gendisk结构,分配并初始化一个请求队列,请求处理函数的编写(request_fn),还有中断的处理等等。但具体到不同的设备,实现又有一些出入,我们在上面看到的IDE设备,它大部分工作都是在IDE总线级上实现了,它做了许多繁琐但必要的工作,并向下层特定设备提供统一的接口,这样就大大简化了块设备驱动的编写过程。

       有兴趣可以参考一下内核ramdisk的实现。

MBR-LBA48位资料 操作系统基础,可以编译成bin文件,直接写入MBR,也可以作为写入MBR的工具 立即下载

相关推荐

SAP MIGO屏幕增强的具体实施步骤介绍(SE19:MB_MIGO_BADI) <转载>

1.MIGO抬头屏幕增强具体增强实施步骤1.1.创建存储抬头客制化数据的增强表1.2.创建增强结构1.3.创建函数组ZMM_MIGO1.3.1.定义全局变量1.3.2.创建数据处理函数1.4.创建字屏幕9001屏幕PBOendif.endloop.1.5.实施新BADI增强SE19创建BADI实施双击实施类ZCL_MIGO_EN_01exportingendif.endmethod.endif.endif.exportingendmethod.

qq_55488207的博客 4510

操作系统真相还原_第3章:8086汇编硬件交互

笔记

dc12499574的博客 1245

给MATLAB安装runtime插件

输入你刚刚下载压缩包的位置(小白提示:在 此电脑 中找到压缩包位置,右键属性复制位置)(!设置好以后然后填写下面输出exe文件的信息,包括文件的名字、作者、Email、公司、概述、描述,下面还可以选择额外的安装选项,exe文件运行需要的其他文件(图像、子程序等)、提供给用户的文件(readme.txt等)(很多方法是官网下载,但在官网下载还是会版本不对应,所以直接在你所用的MATLAB里搜索安装链接最靠谱)(!5.可以打包程序了(你发送文件的人电脑里没有MATLAB也可以查看运行你的程序了)

Pei_hua100的专栏 1万+

【FAQ】存储基础知识 - 磁盘寻址(CHS寻址方式、LBA寻址方式)

【FAQ】存储基础知识 - 磁盘寻址       1、磁盘寻址 1.1、磁盘驱动器 维基百科网址:http://en.wikipedia.org/wiki/Hard_disk_drive 磁盘物理结构图如下:                         磁盘逻辑组成图如下:   1.2、什么是CHS(cylinder head sector) 维基百

haiross的专栏 2万+

拓扑优化背后的科学:ANSYS Workbench中的算法与原理

本文深入解析了ANSYS Workbench中拓扑优化的科学原理与算法实现,重点介绍了密度法(SIMP)和灵敏度分析等核心算法。通过分层架构解析和参数调优实战,展示如何有效进行模型验证与多物理场耦合优化,帮助工程师提升结构设计效率与性能。

weixin_29250403的博客 417

NA400与昆仑通态MODBUS/TCP通讯调试说明

点击增加设备通道,弹出窗口进行设置,通道类型选择“0区输出继电器”,通道地址为1,通道个数为1,读写方式为读写。点击增加设备通道,弹出窗口进行设置,通道类型选择“4区输出寄存器”,数据类型选择“16位 无符号二进制”,通道地址为21001,通道个数为1,读写方式为读写。5.添加设备通道:双击莫迪康MODBUSTCP子设备,点击添加设备通道,根据Modbus规约地址表进行参数的设置,表格可在NAPro软件帮助中查看,如下图所示。然后可以在设备通道调试数据中观察到Q1的值为1,NW1的值678,表示通讯成功。

weixin_44281509的博客 2490

【读书笔记】从实模式到保护模式

用电表示数据寄存器的作用:具有记忆功能的器件。锁存可以通过下面的开关控制,平时开关为空,按下开关之后,将输入锁存起来。锁存之后右面灯泡就就不会变化了,除非再次按下锁存开关。下面的开关是关着的,有间隙,是上下按的。带有寄存器的加法机如何工作:每次输入/数字后存入寄存器,而不是多组线进行输入。再入加减乘除就是多了其他控制开关,上面的加减乘除是每个开关,其他控制的地方也可以用一组01值来表示各类操作。

努力充实,远方可期 1550

手把手教你用Arduino IDE玩转ESP32-S3-wroom(附串口调试技巧)

本文详细介绍了如何在Arduino IDE环境下配置和使用ESP32-S3-WROOM模块,包括开发环境搭建、硬件连接、程序烧录及高级调试技巧。通过实战步骤和常见问题解决方案,帮助开发者快速上手这一高性能Wi-Fi/蓝牙双模模组,提升物联网开发效率。

weixin_30487201的博客 292

关于硬盘读写

这是所发的第一篇blog,是在学习操作系统时的一个问题,内容本是写给一个老师的问题,但最终没收到回复,在此留下,以提示自己思考,若阁下有解决思路,还请一定告知,谢谢!问题大概是这样,我写了段操作系统的引导代码,试图引导操作系统,而引导操作系统的必要一步就是读取pbr,然后跳转到pbr的代码上,而问题就出在读硬盘上,读硬盘可以通过int13中断(测试成功),但此法不能读...

weixin_34019144的博客 207

库存管理系统项目部署方案(基于jdk17)

不需要安装到服务器,运维本地安装就行,主要是用来编译前端代码的。构建完成后将dist文件夹复制到服务器内。

程序员诚哥 6367

如何利用Dpabi,AFNI,FSL软件计算种子点的功能连接?

fsl_glm 得到的是线性回归系数(beta coefficient),由于在自变量和因变量标准化(均值为 0,标准差为 1)的情况下,简单线性回归的回归系数和皮尔逊相关系数是相同的,因此这是一种间接的方法。(3)上一步得到的 PCC.nii.gz 文件是 Harvard-Oxford 概率模板中的后扣带回,每个体素中的数值(1-100)表示该体素属于 PCC 的概率,反映 PCC 在不同被试中的变异大小,也表示我们对于某个体素属于PCC 的信心。接下来,我们来聊聊功能连接在数据处理里的具体应用。

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 7842

Linux Kernel 3.10内核源码分析--块设备层request plug/unplug机制

一、基本原理 Linux块设备层使用了plug/unplug(蓄流/泄流)的机制来提升IO吞吐量。基本原理为:当IO请求提交时,不知直接提交给底层驱动,而是先将其放入一个队列中(相当于水池),待一定时机或周期后再将该队列中的请求统一下发。将请求放入队列的过程即plug(蓄流)过程,统一下发请求的过程即为unplug(泄流)过程。每个请求在队列中等待的时间不会太长,通常在ms级别。 如此设计,可

omnispace的博客 1946

Unreal5从入门到精通 专栏目录

欢迎来到“UE5从入门到精通”专栏!在这里,我们将带您踏上一段精彩的旅程,深入探索虚幻引擎5(Unreal Engine 5)的无限可能。不论您是游戏开发的新手,还是希望提升技能的开发者,这里都有适合您的内容。基础知识:了解虚幻引擎5的界面、功能和基本操作,为您的学习打下坚实的基础。项目实战:通过实际项目案例,帮助您从理论走向实践,真实体验游戏开发的每个环节。高级技巧:分享各种高级功能和技巧,包括蓝图、C++编程、材质编辑、光照和渲染等,让您能够创作出更具专业水准的作品。

TxNet 2987

linux sd卡驱动分析

原文地址:linux sd卡驱动分析 作者:shark888 linux sd卡驱动分析 (2012-01-30 16:48)转载 标签:  linux  class  normal  color  Linux  分类: 驱动系列 基于S3C2410的SD卡linux驱动工作原理  Linux MMC/SD/SDIO体系结构 linux sd卡驱动分析

Hens007的专栏 9638

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

戏说文件系统之ext3【上】

今天我们简单聊一哈ext3文件系统。ext3作为ext2的增强版,和ext2使用的superblock、inode、group descriptor等数据结构几乎一模一样,所以ext3前向兼容ext2。在不用备份ext2文件系统数据的情况下,可以用: tune2fs –j /dev/hdName 在不用卸载分区的状态下直接将ext2文件系统转换成ext3文件...

weixin_30895603的博客 176

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

基于S3C2410的SD卡linux驱动工作原理

Linux MMC/SD/SDIO体系结构 linux sd卡驱动分析                  基于S3C2410的SD卡linux驱动工作原理  我在讲嵌入式Linux驱动开发班的时候,发现不少学员对SD卡驱动这块比较感兴趣,课下来找我探讨。而在很多技术论坛,也有不少人问这方面的问题,所以就想写一

bingqingsuimeng的专栏 1828

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

基于S3C2410的SD卡linux驱动工作原理(二)

序:我在讲嵌入式Linux驱动开发班的时候,发现不少学员对SD卡驱动这块比较感兴趣,课下来找我探讨。而在很多技术论坛,也有不少人问这方面的问题,所以就想写一下这方面的内容,希望对大家的学习能有所帮助。 前几天写了篇“基于S3C2410的SD卡linux驱动工作原理(一)”,说了下脱离操作系统如何在S3C2410上实现SD卡的读写。了解了脱离操作系统的工作原理后,现在可以思考linux是如何管理管...

mmdev 110

linux-2.6.22.6内核nand flash框架分析

总结:块设备和字符设备这两类存储类驱动最终都会用到nand_scan_tail里面构造的mtd_info信息,最终的的读写函数都会定位到mtd_info的具体函数,不过块设备更复杂,分层更多,它主要分为硬件层、nand协议层和块设备层,硬件层知道怎样发命令,需要构造nand_chip结构体,协议层知道要发什么来操作。主要构造mtd_info结构体,块设备层使用mtd_info信息,并用电梯调度算法进行优化。

qq_34429554的博客 329

linux日志型文件系统,Linux日志型文件系统的研究及其性能优化

摘要:Linux支持众多文件系统,从日志型文件系统到集群文件系统和加密文件系统。其中,作为Linux固有的文件系统,EXT2文件系统是最广泛采用的非日志型文件系统。但在日常使用中,断电故障或系统崩溃这样不可预测的事件可能导致文件系统处于不一致状态,为克服这一问题而采用的自动进行的一致性检查e2fsck将对整个磁盘进行全面彻底地检查和修复,并能有效地修复因断电或崩溃等异常带来的不一致问题,保证了文件...

weixin_39991222的博客 202

Linux 2.6.20 SD/MMC卡驱动架构与实现解析

SD/MMC卡驱动是Linux存储子系统的核心组件,采用分层架构设计实现硬件抽象与协议栈分离。从块设备层、核心协议层到主机控制器驱动层,每层通过标准接口交互,这种设计提升了代码复用率和跨平台兼容性。在嵌入式开发中,理解MMC总线注册、卡检测机制和DMA传输优化等关键技术,对存储设备驱动开发至关重要。以S3C2440平台为例,驱动初始化涉及工作队列创建、中断注册和时钟配置等关键步骤,而mmc_rescan()函数则实现了卡识别与初始化的完整流程。通过分析struct mmc_host等核心数据结构,开发者可以

weixin_42522374的博客 314

Linux 块设备层中的Multi-queue分析

目前,百万甚至千万级别的IOPS数据访问量已成为一个大趋势,并且当前的SSD展现着越来越高效的性能表现。在这种趋势下linux的块设备层渐渐成为了整体系统性能提升的主要瓶颈。本文主要讨论的是在多核系统下,如何利用Multi-queue减小块设备层对整体性能的影响。 传统的块设备层针对于千/万级别的IOPS数据访问量是有所余力的,但是面对与日俱增的大数据访问,特别是在底层SSD提供更高速的访问性能...

yedushu的博客 3455

RPO与RTO视角下的CDP技术实现:从定时备份到IO级连续捕获的演进分析

企业灾备与数据保护技术实战,涵盖CDP持续保护、数据库备份、异地容灾架构等核心技术。

2601_96373668的博客 353

Linux块设备层架构与性能优化解析

块设备是Linux存储子系统的核心组件,负责将文件系统的抽象I/O请求转化为具体的存储设备操作。其核心架构包括通用块层、I/O调度层和设备映射层,通过多队列(blk-mq)机制和智能调度算法(如CFQ、Deadline)实现高性能存储访问。在现代SSD和NVMe设备场景下,NOOP和Kyber调度器能显著提升IOPS和降低延迟。开发实践中需关注request_queue和bio等关键数据结构,通过blktrace等工具进行性能分析和优化。这些技术广泛应用于云计算存储、数据库系统等高性能场景,是理解Linux

weixin_29232507的博客 277

Linux文件系统概述:硬盘驱动>通用块设备层>文件系统>虚拟文件系统(VFS)

目录 一.概述 1. 硬盘驱动 2. 通用块设备层 General Block Device Layer 3. 文件系统 4. 虚拟文件系统(VFS) 二.存储介质 闪存(Flash Memory) 外存 内存 1. 基于FLASH的文件系统 (1) jffs2 (2) yaffs:Yet Another Flash File System (3) Cramfs:Compressed ROM File System (4) Romfs 2. 基于RAM的文件系统 (1) Ra

RToax 3203

Multi-queue 架构分析

Linux上传统的块设备层(Block Layer)和IO调度器(如cfq)主要是针对HDD(hard disk drivers)设计的。我们知道,HDD设备的随机IO性能很差,吞吐量大...

内核工匠 4950
上一篇: 块设备层分析2
下一篇: RamDisk块设备驱动实例开发讲解
xp_super
博客等级 码龄14年 10粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值