12 M.2 硬盘
1 M.2 接口介绍
M.2 接口是一种物理接口标准,它可以支持多种不同的通信协议,包括:
- PCIe(Peripheral Component Interconnect Express)
- SATA(Serial Advanced Technology Attachment)
- USB(Universal Serial Bus)
因此,M.2 接口的速度和性能取决于所使用的通信协议和硬件实现。M.2 接口可以支持 PCIe 3.0,这是一种高速的数据传输协议,通常用于连接图形卡、固态硬盘(SSD)以及其他需要高带宽的设备。
在现代计算机中,尤其是消费级领域,M.2接口最为常见和重要的应用就是连接固态硬盘(SSD)。而我们通常所说的'M.2 SSD',根据协议不同,主要分为两类:
- 性能更高的NVMe协议(运行在PCIe总线上)
- 与传统SATA硬盘性能相当的SATA协议
简单理解
M.2是'插槽和外观',PCIe是'高速公路',SATA是'普通公路',而NVMe是跑在高速公路上的'超级交通规则'。我们通过M.2这个物理接口,可以选择让硬盘使用哪条'路'和哪套'规则'。
1.1 M.2 插槽规格
M.2 插槽有不同的物理尺寸,包括:
- 2242
- 2260
- 2280
- 22110
这些数字表示了插槽的长度和宽度。
1.2 RK3568 PCIe 架构
RK3568 芯片拥有:
- 1个 PCIe3.0 x2 Lane Dual Mode 控制器
- 1个 PCIe3.0 x1 Lane RC Mode控制器
- 1个 PCIe3.0 x2 Lane PHY
PCIe3.0 x2 Lane Dual Mode 控制器和 PCIe3.0 x1 Lane RC Mode 控制器都连接到 PCIe3.0 x2 Lane PHY,即两个控制器连接同一个 PHY。
连接示意图如下:
2 M.2 接口的板卡位置
开发板的M.2接口规格:
- PCIe类型:PCIe Gen3 x 2 lane
- 长度规格:2280
- 协议支持:该接口只能搭配M2 NVMe协议的固态硬盘
3 M.2硬盘使用---命令行方式
3.1 设备树文件讲解
提示
下文的文件路径:out/kernel/src_tmp/linux-5.10/arch/arm64/boot/dts/rockchip 需要先编译码源。
PCIe 所用的引脚属于专用引脚,只需要启用对应的控制器,对应的引脚将被设置成对应的模式。
提示
虽然这部分DTS代码较长,但需要用户修改的地方很少,主要是修改 status
属性为 okay
,所以本章节的DTS并不进行详细解析,只展示关键代码和做简单说明!
先看基础定义层 (rk3568.dtsi),由于篇幅有限,只展示pcie30phy和pcie3x2 节点的代码,其他节点只是寄存器地址以及使用的PHY不一样。
pcie30phy: phy@fe8c0000 {
compatible = "rockchip,rk3568-pcie3-phy";
reg = <0x0 0xfe8c0000 0x0 0x20000>;
#phy-cells = <0>;
clocks = <&pmucru CLK_PCIE30PHY_REF_M>, <&pmucru CLK_PCIE30PHY_REF_N>,
<&cru PCLK_PCIE30PHY>;
clock-names = "refclk_m", "refclk_n", "pclk";
resets = <&cru SRST_PCIE30PHY>;
reset-names = "phy";
rockchip,phy-grf = <&pcie30_phy_grf>;
status = "disabled";
};
pcie3x2: pcie@fe280000 {
compatible = "rockchip,rk3568-pcie", "snps,dw-pcie";
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x20 0x2f>;
clocks = <&cru ACLK_PCIE30X2_MST>, <&cru ACLK_PCIE30X2_SLV>,
<&cru ACLK_PCIE30X2_DBI>, <&cru PCLK_PCIE30X2>,
<&cru CLK_PCIE30X2_AUX_NDFT>;
clock-names = "aclk_mst", "aclk_slv",
"aclk_dbi", "pclk", "aux";
device_type = "pci";
interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "sys", "pmc", "msg", "legacy", "err";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
<0 0 0 2 &pcie3x2_intc 1>,
<0 0 0 3 &pcie3x2_intc 2>,
<0 0 0 4 &pcie3x2_intc 3>;
linux,pci-domain = <2>;
num-ib-windows = <6>;
num-ob-windows = <2>;
max-link-speed = <3>;
msi-map = <0x2000 &its 0x2000 0x1000>;
num-lanes = <2>;
phys = <&pcie30phy>;
phy-names = "pcie-phy";
power-domains = <&power RK3568_PD_PIPE>;
ranges = <0x00000800 0x0 0x80000000 0x3 0x80000000 0x0 0x800000
0x81000000 0x0 0x80800000 0x3 0x80800000 0x0 0x100000
0x83000000 0x0 0x80900000 0x3 0x80900000 0x0 0x3f700000>;
reg = <0x3 0xc0800000 0x0 0x400000>,
<0x0 0xfe280000 0x0 0x10000>;
reg-names = "pcie-dbi", "pcie-apb";
resets = <&cru SRST_PCIE30X2_POWERUP>;
reset-names = "pipe";
/* rockchip,bifurcation; lane0 when using 1+1 */
status = "disabled";
pcie3x2_intc: legacy-interrupt-controller {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>;
};
};
以上是pcie3x2节点的代码,rk3568提供的三个PCIE控制器如下:
- pcie2x1 :PCIe 2.0单通道控制器,寄存器地址0xfe260000,使用combphy2_psq作为PHY
- pcie3x1 :PCIe 3.0单通道控制器,寄存器地址0xfe270000,使用pcie30phy作为PHY,支持bifurcation模式
- pcie3x2 :PCIe 3.0双通道控制器,寄存器地址0xfe280000,使用pcie30phy作为PHY,支持bifurcation模式 每个控制器都配置了相应的时钟源、中断、电源域和复位信号,默认状态为disabled。
再看引脚配置层(rk3568-pinctrl.dtsi):
pcie20m0_pins: pcie20m0-pins {
rockchip,pins =
/* pcie20_clkreqnm0 */
<0 RK_PA5 3 &pcfg_pull_none>,
/* pcie20_perstnm0 */
<0 RK_PB6 3 &pcfg_pull_none>,
/* pcie20_wakenm0 */
<0 RK_PB5 3 &pcfg_pull_none>;
};
pcie30x1m0_pins: pcie30x1m0-pins {
rockchip,pins =
/* pcie30x1_clkreqnm0 */
<0 RK_PA4 3 &pcfg_pull_none>,
/* pcie30x1_perstnm0 */
<0 RK_PC3 3 &pcfg_pull_none>,
/* pcie30x1_wakenm0 */
<0 RK_PC2 3 &pcfg_pull_none>;
};
pcie30x2m0_pins: pcie30x2m0-pins {
rockchip,pins =
/* pcie30x2_clkreqnm0 */
<0 RK_PA6 2 &pcfg_pull_none>,
/* pcie30x2_perstnm0 */
<0 RK_PC6 3 &pcfg_pull_none>,
/* pcie30x2_wakenm0 */
<0 RK_PC5 3 &pcfg_pull_none>;
};
每个PCIE控制器都提供多种引脚复用模式(m0、m1、m2),每种配置包含三个关键信号:
- clkreqn :时钟请求信号,用于电源管理
- perstn :复位信号,用于硬件复位控制
- waken :唤醒信号,用于从低功耗状态唤醒
最后看板级配置层 (rk3568-evb6-ddr3-v10.dtsi)
&pcie30phy {
status = "okay";
};
&pcie2x1 {
reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&pcie20_3v3>;
status = "okay";
};
&pcie3x1 {
rockchip,bifurcation;
reset-gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&pcie30_3v3>;
status = "okay";
};
&pcie3x2 {
rockchip,bifurcation;
reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&pcie30_3v3>;
status = "okay";
};
- 启用PHY : &pcie30phy 节点设置 status = "okay" 来启用PCIe 3.0 PHY
- 配置复位GPIO :通过 reset-gpios 属性指定复位控制引脚
- 配置电源供应 :通过 vpcie3v3-supply 属性关联3.3V电源调节器
- 启用bifurcation模式 :对于PCIe 3.0控制器,可通过 rockchip,bifurcation 属性启用通道分叉功能
- 启用控制器 :设置 status = "okay" 来启用相应的PCIE控制器
警告
硬盘和TF卡不一样,不支持热插拔! 请确保在安装固态硬盘前,系统已关闭,以避免数据丢失
用户需要在断电状态下安装好固态硬盘后,再启动系统。
3.2 测试M.2 SSD的常用命令
安装好硬盘后,与TF卡操作一样使用指令即可。
使用 下面指令查看挂载目录后,进入挂载目录即可查看文件并通过命令行进行操作。
df -h
3.3 M.2 硬盘使用的具体演示
查看挂载目录:
查看硬盘内容: