使用 OHCI-1394 火线控制器提供的物理 DMA 进行调试¶
简介¶
基本上,目前使用的所有火线控制器都符合 OHCI-1394 规范,该规范将控制器定义为 PCI 总线主设备,它使用 DMA 从 CPU 卸载数据传输,并具有“物理响应单元”,该单元通过在应用 OHCI-1394 驱动程序定义的过滤器后,采用 PCI 总线主 DMA 来执行特定请求。
正确配置后,远程计算机可以发送这些请求,要求 OHCI-1394 控制器对物理系统内存执行读取和写入请求,对于读取请求,将物理内存读取的结果发送回请求者。
这样,就可以通过读取诸如 printk 缓冲区或进程表之类的感兴趣的内存位置来调试问题。
也可以通过火线检索完整的系统内存转储,数据传输速率在 10MB/s 或更高。
对于大多数火线控制器,内存访问仅限于物理地址空间的低 4 GB。这在内存主要位于该限制以上的机器上可能会成为问题,但在诸如 x86、x86-64 和 PowerPC 之类的更常见的硬件上很少有问题。
已知至少 LSI FW643e 和 FW643e2 控制器支持访问 4 GB 以上的物理地址,但 Linux 目前未启用此功能。
结合用于调试的 OHCI-1394 控制器的早期初始化,此功能对于检查 printk 缓冲区中的长调试日志以调试诸如 ACPI 之类的区域中的早期启动问题非常有用,在这些区域中,系统无法启动,并且其他调试方法(串行端口)要么不可用(笔记本电脑),要么对于广泛的调试信息(如 ACPI)来说太慢。
驱动程序¶
drivers/firewire 中的 firewire-ohci 驱动程序默认使用经过过滤的物理 DMA,这更安全,但不适用于远程调试。将 remote_dma=1 参数传递给驱动程序以获得未过滤的物理 DMA。
由于 firewire-ohci 驱动程序依赖于 PCI 枚举才能完成,因此为 x86 实现了在很早运行的初始化例程。此例程在调用 console_init() 之前很久运行,即在 printk 缓冲区出现在控制台上之前。
要激活它,请启用 CONFIG_PROVIDE_OHCI1394_DMA_INIT (内核黑客菜单:在启动早期通过火线进行远程调试),并在启动时将参数“ohci1394_dma=early”传递给重新编译的内核。
工具¶
firescope - 最初由 Benjamin Herrenschmidt 开发,Andi Kleen 将其从 PowerPC 移植到 x86 和 x86_64 并添加了功能,firescope 现在可用于查看远程计算机的 printk 缓冲区,即使是实时更新。
Bernhard Kaindl 增强了 firescope 以支持从 32 位 firescope 访问 64 位机器,反之亦然:- http://v3.sk/~lkundrak/firescope/
他还实现了快速系统转储(alpha 版本 - 请阅读 README.txt):- http://halobates.de/firewire/firedump-0.1.tar.bz2
还有一个火线的 gdb 代理,允许使用 gdb 访问可通过 gdb 在 vmlinux 中找到的符号引用的数据:- http://halobates.de/firewire/fireproxy-0.33.tar.bz2
此 gdb 代理 (fireproxy-0.34) 的最新版本可以通过基于内存的通信模块 (kgdbom) 与 kgdb 进行通信(尚未稳定)。
入门¶
OHCI-1394 规范规定 OHCI-1394 控制器必须在每次总线复位时禁用所有物理 DMA。
这意味着,如果您想调试处于禁用中断且不对 OHCI-1394 控制器进行总线复位轮询的系统状态中的问题,则必须在系统进入此类状态__之前__建立任何火线电缆连接并完全初始化所有火线硬件。
使用带有早期 OHCI 初始化的 firescope 的分步说明
验证您的硬件是否受支持
加载 firewire-ohci 模块并检查您的内核日志。您应该看到类似于
firewire_ohci 0000:15:00.1: added OHCI v1.0 device as card 2, 4 IR + 4 IT ... contexts, quirks 0x11
加载驱动程序时。如果您没有受支持的控制器,则可以使用许多完全符合 OHCI-1394 规范的 PCI、CardBus 甚至一些 Express 卡。如果它不需要 Windows 操作系统的驱动程序,则很可能就是。只有专门的商店才有不兼容的卡,它们基于 TI PCILynx 芯片,并且需要 Windows 操作系统的驱动程序。
如果控制器实现了可写的物理上限寄存器,则提到的内核日志消息包含字符串“physUB”。这是 4 GB 以上的物理 DMA 所必需的(但 Linux 尚未利用)。
建立有效的火线电缆连接
任何火线电缆,只要它提供电气和机械稳定的连接并具有匹配的连接器(有小的 4 针和大的 6 针火线端口)即可。
如果驱动程序在两台机器上都在运行,则当电缆插入并连接两台机器时,您应该在两台机器的内核日志中看到类似
firewire_core 0000:15:00.1: created device fw1: GUID 00061b0020105917, S400
的消息。
使用 firescope 测试物理 DMA
在调试主机上,确保可以访问 /dev/fw*,然后启动 firescope
$ firescope Port 0 (/dev/fw1) opened, 2 nodes detected FireScope --------- Target : <unspecified> Gen : 1 [Ctrl-T] choose target [Ctrl-H] this menu [Ctrl-Q] quit ------> Press Ctrl-T now, the output should be similar to: 2 nodes available, local node is: 0 0: ffc0, uuid: 00000000 00000000 [LOCAL] 1: ffc1, uuid: 00279000 ba4bb801
除了 [LOCAL] 节点之外,它必须显示另一个没有错误消息的节点。
准备使用早期 OHCI-1394 初始化进行调试
4.1) 在调试目标上编译和安装内核
编译要调试的内核,并启用 CONFIG_PROVIDE_OHCI1394_DMA_INIT (内核黑客:提供在启动早期通过火线启用 DMA 的代码),并将其安装在要调试的机器(调试目标)上。
4.2) 将调试内核的 System.map 传输到调试主机
将要调试的内核的 System.map 复制到调试主机(通过火线电缆连接到被调试机器的主机)。
检索 printk 缓冲区内容
连接火线电缆,加载调试主机上的 OHCI-1394 驱动程序,重新启动已启用 CONFIG_PROVIDE_OHCI1394_DMA_INIT 的内核的被调试机器,并使用选项 ohci1394_dma=early。
然后,在调试主机上,运行 firescope,例如使用 -A
firescope -A System.map-of-debug-target-kernel
注意:-A 会自动附加到第一个非本地节点。仅当仅使用火线连接了两台机器时,它才能可靠地工作。
附加到调试目标后,按 Ctrl-D 查看完整的 printk 缓冲区,或按 Ctrl-U 进入自动更新模式并获取调试目标上记录的最新内核消息的实时视图。
调用“firescope -h”以获取有关 firescope 选项的更多信息。
注释¶
文档和规范: http://halobates.de/firewire/
FireWire 是 Apple Inc. 的商标 - 有关更多信息,请参阅: https://en.wikipedia.org/wiki/FireWire