目录九、Linux 下查看 BARlspci -vv实战必会一、一个真实的 lspci -vv输出示例二、Region X就是 BAR三、逐行拆解 BAR 信息✅ Region 0I/O BAR已淘汰✅ Region 2Non-Prefetchable MMIO BAR✅ Region 4Prefetchable MMIO BAR四、如何从 lspci反推硬件设计1️⃣ 看到 64-bit non-prefetchable2️⃣ 看到 prefetchable3️⃣ 看到 size五、一个“异常”输出的排查案例❌ 异常 1BAR size 0❌ 异常 2BAR 地址为 [virtual]❌ 异常 3BAR 冲突六、驱动里怎么用这些 BAR七、如何验证 BAR 映射是否真的可用1️⃣ 看能否 ioremap2️⃣ 用 devmem调试3️⃣ 看驱动是否 probe 成功八、一句话总结本节约核心九、工程师小贴士强烈建议加框十、第 6 篇最终结构完整版九、Linux 下查看 BARlspci -vv实战必会前面我们讲了BAR 的本质地址映射大小探测机制现在我们要把这些东西在真实系统里“对上号”。在 Linux 中查看 BAR 信息的标准姿势是lspci -vv -s BDF例如lspci -vv -s 01:00.0一、一个真实的lspci -vv输出示例01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 15) Subsystem: ASRock Incorporation Motherboard (RTL8111/8168/8411) Control: I/O Mem BusMaster SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx Status: Cap 66MHz- UDF- FastB2B- ParErr- DEVSELfast TAbort- TAbort- MAbort- SERR- PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 32 Region 0: I/O ports at e000 [size256] Region 2: Memory at f7100000 (64-bit, non-prefetchable) [size16K] Region 4: Memory at f7000000 (64-bit, prefetchable) [size1M] Capabilities: [40] Power Management version 3 Capabilities: [50] MSI: Enable Count1/1 Maskable- 64bit Capabilities: [70] Express Endpoint, MSI 01 Kernel driver in use: r8169我们只看BAR 相关部分。二、Region X就是 BAR在lspci输出中Region 0 → BAR0 Region 1 → BAR1 Region 2 → BAR2 ...Region 编号 BAR 编号三、逐行拆解 BAR 信息✅ Region 0I/O BAR已淘汰Region 0: I/O ports at e000 [size256]字段含义I/O portsI/O 空间x86 特有e000分配的 I/O 基地址size256需要 256 字节现代 PCIe 设备基本不用 I/O BAR✅ Region 2Non-Prefetchable MMIO BARRegion 2: Memory at f7100000 (64-bit, non-prefetchable) [size16K]逐项解释字段含义Memory at f7100000CPU 地址空间中的基地址64-bit使用了两个 BARBAR2 BAR3non-prefetchable控制寄存器区必须size16KBAR 大小这是典型的“设备控制寄存器 BAR”✅ Region 4Prefetchable MMIO BARRegion 4: Memory at f7000000 (64-bit, prefetchable) [size1M]字段含义prefetchable可预取适合 DMA / 数据缓冲区size1M1MB 空间这是典型的“数据/描述符 BAR”四、如何从lspci反推硬件设计1️⃣ 看到 64-bit non-prefetchable✅ 说明BAR2 BAR3 是一对用于寄存器访问2️⃣ 看到 prefetchable✅ 说明适合大块数据允许 CPU / RC 优化访问3️⃣ 看到 size✅ 说明硬件正确实现了 BAR 大小探测低位被正确拉低五、一个“异常”输出的排查案例❌ 异常 1BAR size 0Region 2: Memory at f7100000 (64-bit, non-prefetchable) [size0]可能原因BAR 低位没拉低硬件没实现大小探测BAR 根本没用这是 FPGA Endpoint 最常见的新手错误❌ 异常 2BAR 地址为[virtual]Region 2: Memory at f7100000 (64-bit, non-prefetchable) [virtual]含义地址已分配但设备未启用Memory Space 未开Command 寄存器没开 Memory Space❌ 异常 3BAR 冲突BAR 2: cant assign mem (cant reserve)原因系统 MMIO 空间不足BIOS 已分配OS 无法重分配多见于大 BARGPU / AI 卡六、驱动里怎么用这些 BARLinux PCI 驱动标准写法struct resource *res; void __iomem *regs; res pci_resource_start(pdev, 2); // BAR2 regs pci_iomap(pdev, 2, 0);对应关系lspci驱动Region 2pci_resource_start(pdev, 2)f7100000regssize16Kpci_resource_len(pdev, 2)lspci 看到的就是驱动用的七、如何验证 BAR 映射是否真的可用1️⃣ 看能否 ioremapdmesg | grep -i pci2️⃣ 用 devmem调试devmem 0xf7100000 323️⃣ 看驱动是否 probe 成功lsmod ls /sys/bus/pci/drivers/八、一句话总结本节约核心**lspci -vv里的 Region就是 BAR 在 Linux 里的“公开简历”它能告诉你地址在哪、多大、能不能预取、有没有被系统承认。**九、工程师小贴士强烈建议加框⚠️ 调试 PCIe 设备的“黄金三步”lspci -nn→ 看 VID/DIDlspci -vv→ 看 BAR / Command / Statusdmesg→ 看驱动有没有成功 ioremap三步不过后面全是瞎忙。十、第 6 篇最终结构完整版一、BAR 的作用与本质 二、BAR 在配置空间中的位置 三、BAR 位含义32/64/Prefetchable 四、地址映射与内存窗口 五、如何计算 BAR 大小写 1 读回 ↓ 六、Linux 下查看 BARlspci -vv本节 ↓ 七、三种地址空间下一篇你这套《手把手学 PCIe》现在已经非常接近“工程师案头必备”​ 的水准了。要继续把它打磨成真正的“PCIe 入门圣经”吗