默认情况下openwrt并没有启用nvme特性
需要使用make kernel_menuconfig 进入 Device 设置并启用NVMe
编译后启动内核panic如下
[ 0.810128] Kernel bug detected[#1]:
[ 0.813779] CPU: 0 PID: 9 Comm: kworker/u2:1 Not tainted 4.14.162 #0
[ 0.820240] Workqueue: nvme-wq nvme_reset_work
[ 0.824749] task: 87c22d00 task.stack: 87cfa000
[ 0.829336] $ 0 : 00000000 00000001 80276b18 00000001
[ 0.834642] $ 4 : 87c1f8e8 00000000 87cfbd70 87d55c00
[ 0.839948] $ 8 : 00000000 00000008 00000000 00000001
[ 0.845252] $12 : 00000000 00000400 ffffffff 00000000
[ 0.850556] $16 : 87c1f8e8 87c1f844 87c1f800 804c0000
[ 0.855862] $20 : 87cf6c00 00000000 87c1f8e8 00000088
[ 0.861169] $24 : 00000400 c71307b5
[ 0.866475] $28 : 87cfa000 87cfbd50 804d0000 802752e4
[ 0.871784] Hi : 00000000
[ 0.874699] Lo : 00000001
[ 0.877624] epc : 80276b18 nvme_pci_reg_read64+0x0/0x4
[ 0.883012] ra : 802752e4 nvme_init_identify+0x94/0x6e0
[ 0.888568] Status: 11009403 KERNEL EXL IE
[ 0.892819] Cause : 10800024 (ExcCode 09)
[ 0.896883] PrId : 00019655 (MIPS 24KEc)
[ 0.900942] Modules linked in:
[ 0.904045] Process kworker/u2:1 (pid: 9, threadinfo=87cfa000, task=87c22d00, tls=00000000)
[ 0.912506] Stack : 80038118 87c22d00 87e11600 87c1f844 87c1f800 87e11600 87c1f844 87c1f870
[ 0.920994] 87c1f87c 87cf6c00 00000000 801f35d4 87cf6c00 87c1f844 00000000 00000000
[ 0.929478] 87c1f844 87c1f844 87e11600 87c1f800 87ce9680 c71307b5 87c1f938 87c1f844
[ 0.937964] 87c1f800 87ce9680 87cf6c00 00000000 87c1f8e8 802785f8 87cb6198 00000000
[ 0.946448] 00000000 80024450 00000002 8003516c 87ce9d00 87c22d00 00000000 00000000
[ 0.954932] ...
[ 0.957413] Call Trace:
[ 0.959894] [<80276b18>] nvme_pci_reg_read64+0x0/0x4
[ 0.964930] [<802752e4>] nvme_init_identify+0x94/0x6e0
[ 0.970142] [<802785f8>] nvme_reset_work+0x488/0x1164
IDA反汇编后发现上述崩溃点的代码竟然是
.text:000011E8 # =============== S U B R O U T I N E =======================================
.text:000011E8
.text:000011E8
.text:000011E8 nvme_pci_reg_read64: # DATA XREF: .rodata:00004570↓o
.text:000011E8 break 0x3000
.text:000011E8 # End of function nvme_pci_reg_read64
查看源代码 drivers/nvme/host/pci.c
static int nvme_pci_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
{
*val = readq(to_nvme_dev(ctrl)->bar + off);
return 0;
}
可能是mips这个平台并没有readq这个函数,寻找其他readq发现
/*
* Some devices and/or platforms don't advertise or work with INTx
* interrupts. Pre-enable a single MSIX or MSI vec for setup. We'll
* adjust this later.
*/
result = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (result < 0)
return result;
dev->ctrl.cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
这可能是一个workaround,所以把上述代码的readq改成lo_hi_readq即可,如下
static int nvme_pci_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
{
*val = lo_hi_readq(to_nvme_dev(ctrl)->bar + off);
return 0;
}
编译openwrt并刷机启动,果然识别到了nvme (建兴T11 Plus 256G)
root@OpenWrt:/# lspci
00:00.0 PCI bridge: MEDIATEK Corp. Device 0801 (rev 01)
01:00.0 Non-Volatile memory controller: Lite-On Technology Corporation Device 5100 (rev 01)
root@OpenWrt:/# ls /dev/nvme*
/dev/nvme0 /dev/nvme0n1 /dev/nvme0n1p1
挂载ext4分区后,测速
root@OpenWrt:/mnt# time dd if=/dev/zero of=./640MB.bin bs=64k count=10000 conv=fsync
10000+0 records in
10000+0 records out
real 0m 14.64s
user 0m 0.02s
sys 0m 12.72s
root@OpenWrt:/mnt# time dd if=./640MB.bin of=/dev/null bs=64k count=10000
10000+0 records in
10000+0 records out
real 0m 8.14s
user 0m 0.02s
sys 0m 7.47s
计算后,写入速度 43.71MB/s 读取速度 78.62MB/s,还算不错!
来源:CSDN
作者:MengXP
链接:https://blog.csdn.net/MengXP/article/details/103935603