《存储IO路径》专题:NVME盘加载的过程

在深入了解NVMe(NVM Express)SSD(固态硬盘)在Linux系统的加载过程之前,让我们先听一个引人入胜的故事。

在未来的世界里,时间不再是线性流动的,而是呈现出多维度交织的形态。在这个世界中,数据传输的速度超越了光速,人们可以通过意识直接交流。在这个时代的科技支撑下,一位名叫NVMe的勇士诞生了。

NVMe出生在一个被称为“存储谷”的地方,这里充满了智能存储设备,其中不乏一些强大的对手。然而,NVMe有着一种独特的天赋,那就是他能够与Linux系统进行无缝沟通。

在Linux系统的世界里,NVMe发现了一个被称为“存储栈”的地方。这个地方包含了从硬件层到应用层的所有存储技术。NVMe决定深入探索这个神秘的地方,希望能够找到提升存储效率的秘诀。

经过一番探索,NVMe发现了一个叫做“请求队列”的地方。他发现,这里就像是一个时空隧道,能够将来自应用层的请求瞬间传输到硬件层。NVMe心生敬畏,决定深入研究这个奇妙的地方。

于是,NVMe踏上了新的旅程,他深入学习如何使用请求队列,如何优化存储路径,如何提高数据传输速度。在这个过程中,NVMe逐渐成长为一位存储领域的专家。

最后,NVMe成功地掌握了所有技能,他成为了一名存储大师。他将这个多维度的存储世界连接在一起,让数据的流动变得无比顺畅。

听完故事,不够过瘾的话,咱们结合代码进一步挖掘nvme ssd加载过程:

  1. 设备发现和初始化:
    • 在Linux内核中,NVMe设备的发现和初始化主要由PCI子系统和NVMe子系统共同完成。
    • PCI子系统通过扫描PCI总线,发现NVMe设备,并为其创建相应的pci_dev结构体。
    • NVMe子系统通过注册的probe函数(通常为nvme_probe)来初始化NVMe设备,创建相应的nvme_dev结构体,并设置设备的读写策略等属性。
static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)  
{  struct nvme_dev *dev;  int err;  dev = kzalloc(sizeof(struct nvme_dev), GFP_KERNEL);  if (!dev)  return -ENOMEM;  err = nvme_init_device(pdev, dev);  if (err)  goto free_dev;  pci_set_drvdata(pdev, dev);  return 0;  free_dev:  kfree(dev);  return err;  
}

上述代码是NVMe子系统的probe函数,用于初始化NVMe设备。它首先分配一个nvme_dev结构体,然后调用nvme_init_device函数进行设备初始化。最后,将设备实例作为pci_drvdata关联到PCI设备上。

  1. 注册硬盘设备:
    • 在NVMe子系统中,会创建一个名为nvme_queue的结构体,用于管理设备的I/O队列。
    • 通过调用blk_add_disk函数,将NVMe设备注册为一个新的硬盘设备,并创建相应的device_t结构体。
    • 这个结构体包含了设备的属性和管理接口,可以被块层用来管理硬盘的读写操作。
int nvme_register_disk(struct nvme_dev *dev, struct gendisk *disk)  
{  int ret;  // 初始化请求队列,并设置请求处理函数为nvme_ops  ret = blk_init_queue(request_queue_callee(disk), &nvme_ops);  if (ret)  return ret;  // 将NVMe设备注册为一个新的硬盘设备  ret = add_disk(disk);  if (ret)  blk_cleanup_queue(request_queue_callee(disk));  return ret;  
}

上述代码是NVMe子系统注册硬盘设备的函数。它首先调用blk_init_queue函数初始化请求队列,并设置请求处理函数为nvme_ops。然后调用add_disk函数将NVMe设备注册为一个新的硬盘设备。如果注册失败,则清理请求队列。

  1. 加载文件系统:
    • 这部分代码通常不在NVMe子系统中,而是在文件系统相关的模块中。
    • 文件系统的加载过程取决于具体的文件系统类型和配置。例如,对于UBI文件系统,会通过ubi_scan函数扫描并解析UBI引导扇区或超级块。
    • 创建文件系统实例的过程可能会涉及到分配内存、初始化文件系统结构等操作。
int ubi_scan(const char *name, int verbose)  
{  // 扫描并解析UBI引导扇区或超级块  // ...  // 创建UBI文件系统实例  ubi = ubi_alloc(&ubi->vols[0].eba_tbl, vols, vcnt, UBI_EMULATION_FLAGS);  if (!ubi) {  ubi_err("failed to allocate memory for UBI volume structure");  return -ENOMEM;  }  // ...  
}
  1. 挂载文件系统:
    • 在VFS(Virtual File System)模块中,通过调用mount函数来挂载文件系统。
    • 这个函数会创建VFS节点和目录项,并将其关联到文件系统实例上。
    • 挂载成功后,操作系统就可以通过标准的文件读写接口来访问硬盘了。
  1. 访问硬盘:
    • 在块层中,所有的硬盘读写操作都会被抽象为请求(request)结构体。
    • 当应用程序调用read、write等系统调用时,块层会将这些请求封装为一个请求结构体,并将其加入到NVMe设备的I/O队列中。
    • NVMe子系统通过处理这个队列,将请求发送给硬件进行实际的读写操作。
// 请求结构体  
typedef struct request {  // 请求相关字段  
} request;  // 系统调用处理函数  
void system_call_handler(void) {  // 封装请求结构体  request req;  // ...  // 将请求加入到NVMe设备的I/O队列中  enqueue(nvme_io_queue, &req);  
}  // NVMe子系统处理函数  
void nvme_subsystem_handler(void) {  // 处理I/O队列  while (!empty(nvme_io_queue)) {  request *req = dequeue(nvme_io_queue);  // 发送请求给硬件进行实际的读写操作  hardware_io(req);  }  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/64661.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 实现PictureBox从随机选择的文件夹内对图像进行随机播放

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System

是否在业务中使用大语言模型?

ChatGPT取得了巨大的成功,在短短一个月内就获得了1亿用户,并激发了企业和专业人士对如何在他们的组织中利用这一工具的兴趣和好奇心。 但LLM究竟是什么,它们如何使你的企业受益?它只是一种炒作,还是会长期存在? 在这篇文章中我…

MPI内置类型与自定义类型

内置类型 MPI_CHAR: 字符型 MPI_UNSIGNED_CHAR: 无符号字符型MPI_BYTE: 字节型MPI_SHORT: 短整型MPI_UNSIGNED_SHORT: 无符号短整型MPI_INT: 整型MPI_UNSIGNED: 无符号整型MPI_LONG: 长整型MPI_UNSIGNED_LONG: 无符号长整型MPI_FLOAT: 单精度浮点型MPI_DOUBLE: 双精度浮点型M…

python强化学习--gym安装与使用

最近开始学习强化学习,第一步肯定是要学会安装和使用pym,原本以为很简单,事实上确实很简单,但是遇到一个小问题,就是安装gym之后,在应用的过程中,游戏界面没有显示出来,了解后才知道…

原型,原型链,继承(圣杯模式)

经典模式和圣杯模式区别 经典模式和圣杯模式都是用于解决构造函数继承和原型继承的问题,但它们在实现继承的方式上有所不同。 经典模式是通过将子类的原型对象设置为父类的实例来实现继承,然后将子类的构造函数设置为子类本身。这样子类既可以继承父类…

从零开始的Hadoop学习(六)| HDFS读写流程、NN和2NN工作机制、DataNode工作机制

1. HDFS的读写流程(面试重点) 1.1 HDFS写数据流程 1.1.1 剖析文件写入 (1)客户端通过 Distributed FileSystem 模块向 NameNode 请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在。 &#x…

springsecurity+oauth 分布式认证授权笔记总结12

一 springsecurity实现权限认证的笔记 1.1 springsecurity的作用 springsecurity两大核心功能是认证和授权,通过usernamepasswordAuthenticationFilter进行认证;通过filtersecurityintercepter进行授权。springsecurity其实多个filter过滤链进行过滤。…

Google Services Framework 谷歌服务框架的安装以及遇到的常见问题

安装谷歌三件套: 1、Google 服务框架(Google Services Framework)下载地址: https://www.apkmirror.com/apk/google-inc/google-services-framework/ 注意一定要选择与自己手机对应的安卓系统版本的服务框架。 2、Google Play Se…

Java设计模式:四、行为型模式-05:备忘录模式

文章目录 一、定义:备忘录模式二、模拟场景:备忘录模式三、改善代码:备忘录模式3.1 工程结构3.2 备忘录模式模型结构图3.3 备忘录模式定义3.3.1 配置信息类3.3.2 备忘录类3.3.3 记录者类3.3.4 管理员类 3.4 单元测试 四、总结:备忘…

超全的数据可视化大屏设计组件库 sketch格式

随着大屏可视化设计需求的发展,可视化sketch矢量素材变得越来越受欢迎,它可以为设计师提供丰富的设计元素,帮助他们更高效更快速的完成设计任务。 大屏可视化sketch数量素材是B端可视化设计师们最佳设计资源,它可以帮助设计师轻松…

React 18 在组件间共享状态

参考文章 在组件间共享状态 有时候,希望两个组件的状态始终同步更改。要实现这一点,可以将相关 state 从这两个组件上移除,并把 state 放到它们的公共父级,再通过 props 将 state 传递给这两个组件。这被称为“状态提升”&#…

Socket交互的基本流程?

TCP socket通信过程图 什么是网络编程,网络编程就是编写程序使两台连联网的计算机相互交换数据。怎么交换数据呢?操作系统提供了“套接字”(socket)的组件我们基于这个组件进行网络通信开发。tcp套接字工作流程都以“打电话”来生…

python异常

一.什么是异常 异常是一个事件,该事件会在程序执行过程中发生,会影响程序的正常运行。一般情况下,python无法正常处理一个异常,会导致程序中断。在出现异常时,为了不影响程序的正常运行,我们需要捕获异常。…

HTML+JavaScript+CSS DIY 分隔条splitter

一、需求分析 现在电脑的屏幕越来越大,为了利用好宽屏,我们在设计系统UI时喜欢在左侧放个菜单或选项面板,在右边显示与菜单或选项对应的内容,两者之间用分隔条splitter来间隔,并可以通过拖动分隔条splitter来动态调研…

vue3 ref reactive响应式数据 赋值的问题

文章目录 vue3 ref reactive响应式数据 赋值的问题场景1:将响应式数据赋值请求后的数据错误示范:直接赋值正确写法 场景2:响应式数据解构之后失去响应式原因分析解决办法 toRefs/toRef方法创建ref引用对象 vue3 ref reactive响应式数据 赋值的问题 doing…

DBeaver 23.1.5 发布

导读DBeaver 是一个免费开源的通用数据库工具,适用于开发人员和数据库管理员。DBeaver 23.1.5 现已发布,更新内容如下. Data editor 重新设计了词典查看器面板 UI 空间数据类型:曲线几何线性化已修复 数据保存时结果选项卡关闭的问题已解决…

gitee上传本地项目bug

🤮这个破bug不知道浪费了多长时间,以前没有记录,每次都忘记,这次记下来 问题描述 gitee创建仓库,然后根据它提示的如下命令,但一直报错 原因分析: 把命令复制出来,粘贴到Sublime …

vscode 清除全部的console.log

在放页面的大文件夹view上面右键点击在文件夹中查找 console.log.*$ 注意:要选择使用正则匹配 替换为 " " (空字符串)

CSS中可继承与不可继承属性

可继承 1. 字体属性: font、font-style、font-variant、font-weight、font-size、line-height等属性是字体样式的属性,都可以被子元素继承。 2. 文本属性: color、text-indent、text-align、text-decoration、text-transform、letter-spa…

gitlab-rake gitlab:backup:create 执行报错 Errno::ENOSPC: No space left on device

gitlab仓库备份执行 gitlab-rake gitlab:backup:create报错如下: 问题分析:存储备份的空间满 解决方法: 方法1:清理存放路径,删除不需要文件,释放空间。 方法2:创建一个根目录的挂载点&#x…