没有合适的资源?快使用搜索试试~ 我知道了~
首页NVMe驱动详解系列——第一部分
NVMe驱动详解系列,第一部:NVMe驱动初始化与注销。 本系列主要针对linux系统中自带的NVMe驱动,进行详细的分析和学习,从而掌握NVMe以及PCI相关知识。文中所使用的源码是linux4.17.2。 需要提醒的是,阅读本系列文章需要一些linux内核模块、pci总线、内核数据结构以及设备驱动模型相关知识,当然作者会尽全力将内容写得简单易懂,使得读者不需要太深奥的知识。大家可以先尝试看如果阅读遇到问题再回去补充知识也可以的,或者直接邮件给我perftrace@gmail.com。
资源详情
资源评论
资源推荐
!
!
!
!
!
!
NVMe 驱动详解系列!
第一部: NVMe 驱动初始化与注销!
作者:!"#$%#&'"()*&+,-'.*/
/
/
/
/
/
/
/
/
/
/
/
/
/
1 NVMe 驱动详解之一源码和编译!
本系列主要针对 ,+012 系统中自带的 345" 驱动,进行详细的分析和学习,
从而掌握 345" 以及 678 相关知识。文中所使用的源码是 ,+0129-:;-<。/
需要提醒的是,阅读本系列文章需要一些 ,+012 内核模块、!'+ 总线、内核数
据结构以及设备驱动模型相关知识,当然作者会尽全力将内容写得简单易懂,使
得读者不需要太深奥的知识。大家可以先尝试看如果阅读遇到问题再回去补充知
识也可以的,或者直接邮件给我 !"#$%#&'"()*&+,-'.*。/
/ 我们直接进入正题。/
开篇我们先来看下源码的位置和编译方法。/
1.1 模块源码#
/ 345" 相关的代码位于内核源码树的 drivers/nvme 中,我们可以看到主
要有两个文件夹一个是 host,一个 targets.
其中 targets 是用于实现将本系统中的 nvme 设备作为磁盘导出,供其他
服务器或者系统使用的功能。而文件夹 host 是实现 NVMe 磁盘供本系统自己使
用,不会对外提供,这意味着外部系统不能通过网络或者光纤来访问我们的 NVMe
磁盘。如果配置 NVMe target 还需要工具 nvmetcli 工具:
http://git.infradead.org/users/hch/nvmetcli.git
我们这个系列主要针对 host,关于 target 将来有机会再做进一步分析。/
/ 所以后续所有文件都是位于 =#>+"#?@0>*"@A.?% 中。/
1.2 模块诞生#
先来看下 =#>+"#?@0>*"@A.?% 目录中的 5&B"$+,",具体如下。我们发现根据
内核中的参数配置,最多会有5个模块。/
# SPDX-License-Identifier: GPL-2.0
ccflags-y += -I$(src)
obj-$(CONFIG_NVME_CORE) += nvme-core.o
obj-$(CONFIG_BLK_DEV_NVME) += nvme.o
obj-$(CONFIG_NVME_FABRICS) += nvme-fabrics.o
obj-$(CONFIG_NVME_RDMA) += nvme-rdma.o
obj-$(CONFIG_NVME_FC) += nvme-fc.o
nvme-core-y := core.o
nvme-core-$(CONFIG_TRACING) += trace.o
nvme-core-$(CONFIG_NVME_MULTIPATH) += multipath.o
nvme-core-$(CONFIG_NVM) += lightnvm.o
nvme-core-$(CONFIG_FAULT_INJECTION_DEBUG_FS) += fault_inject.o
nvme-y += pci.o
nvme-fabrics-y += fabrics.o
nvme-rdma-y += rdma.o
nvme-fc-y += fc.o
/ 其中 ccflags-y 是编译标记,会被正常的 cc 调用,指定了$(CC)编译时候的
选项,这里只是将内核源码的头文件包含进去。 其中$(src)是指向内核根目录
中 Makefile 所在的目录,包含模块需要的一些头文件。当然,这里其实我们可
以不用纠结或者理睬它。
我们看下决定模块是否编译的5个配置参数:/ /
! NVME_CORE: 这是一个被动的选项。该选项在 BLK_DEV_NVME,
NVME_RDMA, NVME_FC 使能时候会自动选上,是 nvme 核心基础。对应的
代码是 core.c,产生的模块是 nvme-core.ko。另外。这里需要注意的是,
如果使能了配置:
TRACING,NVME_MULTIPATH,NVM,FAULT_INJECTION_DEBUG_FS, 那
么模块 nvme-core.ko 会合入 trace.c,multipath.c,lightnvm.c
和 fault_inject.c 文件,这些是 NVMe 驱动的特点可选择是否开启。
! BLK_DEV_NVME:这个选项开启后会自动选上 NVME_CORE,同时自身依赖
pci 和 block.这个产生 nvme.ko 驱动用于直接将 ssd 链接到 pci 或者
pcie.对应的代码是 nvme.c 和 pci.c,产生的模块是 nvme.ko.
! CONFIG_NVME_FABRICS:是这个被动选项。被 NVME_RDMA 和 NVME_FC
选择(当然,还有一些其他条件需要满足)。主要用于支持 FC 协议。/
! CONFIG_NVME_RDMA:这个驱动使得 NVMe over Fabric 可以通过 RDMA
传输( 该选项还依赖于 CONFIG_INFINIBAND) 。该选项会自动使能
NVME_CORE 和 NVME_FABRICS,SG_POOL/
! CONFIG_NVME_FC:这个驱动使得 NVMe over Fabric 可以在 FC 传输。
该选项会自动使能 NVME_CORE 和 NVME_FABRICS,SG_POOL/
/
模块/
依赖/
源码文件/
0>*"C'.#"-B./
C/
0>*"C'.#"-'D/
%#&'"-'D/
*1,%+!&%A-'D/
,+)A%0>*-'D/
$&1,%E+0F"'%-'/ /
0>*"-B./
0>*"C'.#"/
!'+-'/
0>*"C$&G+#'-B./
C/
$&G#+'?-'/
0>*"C#=*&-B./
0>*"C'.#"D0>*"C$&G+#'D?!E!..,/
#=*&-'/
0>*"C$'-B./
0>*"C'.#"D0>*"C$&G+#'D?!E!..,/
$'-'/
/ 配置完毕后,可以在内核代码根目录中执行 *&B" 命令产生驱动。/
#make M=drivers/nvme/host/
/ 编译后会产生所配置的驱动模块,我们本系列只覆盖 0>*"-B. 这个驱动模板,
当然另一个 0>*"C'.#"-B. 必须的。编译后可以通过 *&B"/*.=1,"?E+0?%&,, 来安装。/
/ 然后可以通过 *.=!#.G"/0>*" 来加载驱动。/
2 NVMe 驱动详解之二 PCI 驱动注册!
我们现在使用的 345" 设备都是基于 678 的,所以最后设备需要连接到内核
中的 !'+ 总线上才能够使用。这也是为什么在上篇配置 0>*"-B. 时会需要 !'+-'
文件,在 5&B"$+," 中有如下这一行的:/
nvme-y += pci.o。/
本篇主要针对 !'+-' 文件的一部分内容进行分析(其实本系列涉及的代码内
容就是在 !'+-' 和 0>*"C'.#"-' 两个文件中)。/
2.1 驱动注册上#
我们先来看下驱动的注册和注销,其实就是模块的初始化和退出函数,如下。/
module_init(nvme_init);
module_exit(nvme_exit);/
可知模块注册函数是 0>*"E+0+%,非常简单,就是一个 !'+E#")+?%"#E=#+>"# 函
数。/
static int __init nvme_init(void)
{
return pci_register_driver(&nvme_driver);
}
/ 注册了 0>*"E=#+>"# 驱动,参数为结构体 0>*"E=#+>"#,该结构体类型是
!'+E=#+>"#。/
static struct pci_driver nvme_driver = {
.name = "nvme",
.id_table = nvme_id_table,
.probe = nvme_probe,
.remove = nvme_remove,
.shutdown = nvme_shutdown,
.driver = {
.pm = &nvme_dev_pm_ops,
},
.sriov_configure = nvme_pci_sriov_configure,
.err_handler = &nvme_err_handler,
};/
/ 我们可以从结构体 0>*"E=#+>"# 中得知,驱动的名字是 0>*";初始化函数
是 0>*"E!#.G",该函数负责在驱动加载时候探测总线上的硬件设备;设备与驱
动的关联表为 0>*"E+=E%&G,",通过这个表内核可以知道哪些设备是通过这个驱
动来工作的;!#.G" 函数,该函数用来初始化设备;#"*.>" 函数,当前驱动从
内核移除时候被调用;?A1%=.H0 函数用于关闭设备I 错误处理句柄
0>*"E"##EA&0=,"#I以及 0>*" 的 ?#+.> 操作函数。/
/ 而 !'+E#")+?%"#E=#+>"# 是个宏,其实是EE!'+E#")+?%"#E=#+>"# 函数,该函数会
通过调用 =#+>"#E#")+?%"# 将要注册的驱动结构体放到系统中设备驱动链表中,将
其串成了一串。这里要注意的是 !'+E=#+>"# 中包含了 =">+'"E=#+>"#D而我们的驱动
剩余31页未读,继续阅读
badman250
- 粉丝: 2367
- 资源: 101
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- 27页智慧街道信息化建设综合解决方案.pptx
- 计算机二级Ms-Office选择题汇总.doc
- 单链表的插入和删除实验报告 (2).docx
- 单链表的插入和删除实验报告.pdf
- 物联网智能终端项目设备管理方案.pdf
- 如何打造品牌的模式.doc
- 样式控制与页面布局.pdf
- 武汉理工Java实验报告(二).docx
- 2021线上新品消费趋势报告.pdf
- 第3章 Matlab中的矩阵及其运算.docx
- 基于Web的人力资源管理系统的必要性和可行性.doc
- 基于一阶倒立摆的matlab仿真实验.doc
- 速运公司物流管理模式研究教材
- 大数据与管理.pptx
- 单片机课程设计之步进电机.doc
- 大数据与数据挖掘.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0