通过数据线调试 Linux 系统设备
引言
本报告旨在为通过数据线连接到计算机的 Linux 系统设备提供全面的调试指南。当图形界面不可用、系统无法启动或需要进行底层诊断时,通过物理数据线(通常是 USB)进行连接和调试至关重要。本报告将涵盖两种主要的连接方法:串行控制台访问和通过 USB 的网络连接。此外,报告还将介绍在建立连接后可用于诊断和解决问题的基础及高级 Linux 调试技术,并提供针对特定流行设备(如树莓派和 BeagleBone Black)的配置示例。最终目标是提供一个结构清晰、信息详实的指南,帮助用户有效地识别连接、建立通信并运用适当的工具来调试目标 Linux 系统。
第 1 节:建立连接
成功调试的第一步是建立计算机与目标 Linux 设备之间的可靠通信链路。这通常涉及物理连接(使用合适的线缆)和在主机和目标设备上进行软件配置。本节将详细介绍如何识别连接的设备,并探讨两种主要的连接方法:串行控制台和 USB 网络。
1.1. 识别设备
在尝试连接之前,必须首先识别 Linux 设备在主机操作系统上是如何被识别的。这取决于设备本身的功能(它是否模拟串行端口、网络适配器或其他设备)以及主机操作系统。
在 Windows 上识别设备:
Windows 系统通常通过设备管理器来识别和管理硬件。
- 打开设备管理器: 可以通过右键单击“开始”按钮并选择“设备管理器”,或者按 Win+R 键,输入 devmgmt.msc 并按 Enter 键来打开 1。
- 查找串行端口 (COM & LPT):
- 如果 Linux 设备通过 USB 转串口适配器连接,或者其 USB 接口模拟了一个串行端口,它通常会出现在“端口 (COM & LPT)”类别下 2。展开此类别,您将看到列出的 COM 端口及其编号,例如 USB Serial Port (COM5) 3。
- 记下分配的 COM 端口号(例如 COM5),因为在配置串行终端软件(如 PuTTY)时需要用到它 5。
- 如果“端口 (COM & LPT)”部分不存在或您的设备未列出,可能表示缺少驱动程序 3。您需要为 USB 转串口适配器或 Linux 设备的 USB 接口安装正确的驱动程序。驱动程序通常由适配器或设备制造商提供。
- 有时,设备可能被隐藏。在设备管理器中,可以尝试点击“查看”菜单并选择“显示隐藏的设备” 1。
- 查找网络适配器 (USB Ethernet):
- 如果 Linux 设备配置为 USB 网络设备(例如,使用 RNDIS 或 CDC Ethernet Gadget 模式),它将出现在“网络适配器”类别下 8。
- 适配器的名称可能因制造商而异(例如,“USB Ethernet/RNDIS Gadget”或特定芯片组名称) 4。
- 您可以使用 ipconfig /all 命令在命令行中查看网络适配器的详细信息,包括其描述和 IP 配置(如果已配置) 8。
- 使用 USBView (可选):
- USBView (usbview.exe) 是 Windows SDK 中包含的一个工具,可以显示连接到计算机的所有 USB 控制器和设备,提供更底层的 USB 信息,如设备描述符 1。这对于识别未正确安装驱动程序的设备或了解其 USB 属性可能很有用。但请注意,它是一个较旧的应用程序,可能无法显示最新的 USB 信息 1。
在 Linux 上识别设备:
Linux 提供了多种命令行工具来识别连接的 USB 设备。
- lsusb:
- 此命令列出所有 USB 总线和连接的设备,显示其 Vendor ID 和 Product ID(例如 ID 346d:5678)以及设备描述 12。
- 运行 lsusb 可以快速确认设备是否被物理检测到,并获取其基本标识符 12。但它通常不直接显示分配的串行设备名称(如 ttyUSB0)或网络接口名称(如 usb0) 12。
- dmesg:
- 此命令显示内核环形缓冲区的内容,其中包含有关硬件检测、驱动程序加载和设备初始化的消息 12。
- 连接设备后立即运行 dmesg 或使用 dmesg | grep <keyword> 进行过滤通常可以找到设备被识别和命名的相关信息。
- 查找串行设备: 使用 dmesg | grep -i tty 15 或 dmesg | grep -i serial 22。输出可能会显示类似 ttyS0(通常是板载串口)或 ttyUSB0(通常是 USB 转串口适配器)的设备名称被分配 15。
- 查找 USB 设备 (通用/网络): 使用 dmesg | grep -i usb 17 或根据 lsusb 获得的 Vendor/Product ID 进行过滤,例如 dmesg | grep ‘idVendor=346d, idProduct=5678’ 12。对于 USB 网络设备,可能会看到与 usb0 或类似接口相关的消息 23。
- 文件系统检查 (/dev 和 /sys):
- 串行设备:
- 检查 /dev 目录中是否存在名为 ttyS* 或 ttyUSB* 的设备文件 20。例如,ls /dev/ttyUSB* 22。
- udev 系统通常会根据设备属性创建持久化的符号链接,例如在 /dev/serial/by-id/ 或 /dev/serial/by-path/ 下 20。这些链接比动态分配的 ttyUSB0、ttyUSB1 等更可靠,因为后者可能会根据设备插入顺序而改变。然而,这些目录并非在所有系统或所有情况下都存在 20。
- /sys/class/tty 目录包含了系统中所有 TTY 设备的信息,可以通过检查其中的条目及其 device/driver 链接来识别真实的串行端口 20。
- USB 设备 (通用): /sys/kernel/debug/usb/devices (需要 debugfs 挂载) 或 /sys/bus/usb/devices/ 包含有关已连接 USB 设备的详细信息 12。
- 串行设备:
- ip addr (或 ifconfig):
- ip addr show (推荐) 或 ifconfig -a (旧版) 命令用于列出系统上的所有网络接口及其配置 13。
- 当 Linux 设备作为 USB Ethernet Gadget 连接时,它在主机上通常会显示为一个名为 usb0(或类似名称,如 enp0s26u1u1 29)的网络接口 23。使用 ip addr show usb0 可以查看该特定接口的详细信息,包括其 IP 地址(如果已配置) 27。
Linux 设备识别工具摘要
工具 (Tool) | 主要用途 (Primary Use) | 示例命令 (Example Command) | 典型输出/查找内容 (Typical Output/What to Look For) |
---|---|---|---|
lsusb | 列出 USB 设备及其 Vendor/Product ID | lsusb | Bus 001 Device 002: ID 1a86:7523 QinHeng Electronics CH340 serial converter |
dmesg | 查看内核消息,识别设备名称分配 | `dmesg \ | grep -i tty<br>dmesg \ |
ip addr (或 ifconfig) | 列出网络接口及其 IP 配置 | ip addr show <br> ip addr show usb0 | 3: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP>… inet 192.168.7.1/24… |
/dev/ | 查找设备文件节点 | ls /dev/ttyUSB* <br> ls /dev/serial/by-id/ | /dev/ttyUSB0 <br> /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0 |
/sys/class/tty | 查看 TTY 设备详细信息 | ls -l /sys/class/tty/ttyUSB0/device/driver | 指向设备驱动程序的符号链接 |
动态与持久化命名:
一个重要的考虑因素是设备名称的稳定性。在 Windows 上,将 USB 转串口适配器插入不同的 USB 端口可能会导致系统分配不同的 COM 端口号 3。同样,在 Linux 上,ttyUSB0, ttyUSB1 等名称的分配顺序可能取决于设备枚举的顺序,这意味着同一个设备在不同次连接时可能会获得不同的名称。对于 USB Ethernet Gadget,如果设备在每次连接时生成随机的 MAC 地址,主机系统可能会将其识别为一个全新的网络接口,导致之前的网络配置(如静态 IP)失效 33。
这种动态命名的不确定性会给重复性的调试工作带来不便。为了获得更稳定的调试设置,建议采用持久化命名的方法:
- Windows: 在设备管理器中,可以为特定的 USB 转串口设备手动分配一个固定的 COM 端口号(在设备属性的“端口设置” -> “高级”中) 3。
- Linux (Serial): 优先使用 /dev/serial/by-id/ 或 /dev/serial/by-path/ 下的符号链接(如果存在),因为它们基于设备的唯一属性或物理连接路径,通常是持久的 20。如果这些链接不存在,可以编写自定义的 udev 规则来为特定设备创建固定的符号链接。
- Linux (USB Ethernet): 在配置 USB Ethernet Gadget 时(例如使用 g_ether 模块),明确指定固定的 MAC 地址(dev_addr 和 host_addr 参数) 23。这可以确保主机系统始终将该设备识别为同一个网络接口,从而使静态 IP 配置等设置保持有效。
1.2. 方法 1:通过串行控制台访问
串行控制台提供了一种直接、低级别的文本接口,用于与 Linux 设备进行通信。它通常在网络连接不可用、系统引导期间或需要进行底层调试时使用 35。
硬件要求:
建立串行连接需要特定的硬件:
- 线缆/适配器:
- USB 转 TTL 串口适配器: 这是最常见的方法,主机通过 USB 连接适配器,适配器提供 TTL 电平(通常为 3.3V 或 5V)的 TX (发送), RX (接收), 和 GND (地线) 引脚,连接到目标 Linux 设备上的相应 UART 引脚 6。常见的适配器芯片包括 CH340, PL2303, CP2102, FT232 6。主机需要安装适配器芯片的驱动程序 3。
- 专用调试线缆: 某些设备(如一些 Android 手机或开发板)可能使用特殊的 MicroUSB 或 USB-C 调试线缆,这些线缆内部包含逻辑,可以通过 USB 端口访问串行控制台(例如 Nexus 调试线缆、Suzy-Q 线缆) 35。这些线缆可能需要特定的电阻值或连接方式才能激活串行模式 35。
- 直接 UART 引脚: 许多嵌入式板(如树莓派、BeagleBone)直接暴露了 UART 的 TX, RX, GND 引脚(通常在 GPIO 排针上) 37。可以直接连接 USB 转 TTL 适配器。
- USB A-A 调试线缆: 存在一种特殊的 USB 3.0 A-A 交叉线缆,用于特定的 USB 调试协议,但这与传统的串行控制台不同,主要用于驱动程序调试,并且不向后兼容 USB 2.0 42。对于本报告讨论的典型 Linux 设备调试场景,通常不使用这种线缆。
- 引脚连接:
- 必须正确连接引脚:主机的 TX 连接到设备的 RX,主机的 RX 连接到设备的 TX,并且 GND 必须相互连接 35。接反 TX 和 RX 是常见的连接错误。
- 电压电平: 务必确保 USB 转串口适配器的电压电平(通常为 3.3V 或 5V)与目标 Linux 设备的 UART 引脚电压电平相匹配 39。连接不匹配的电压可能会损坏设备。一些设备可能使用 1.8V 电平 35。
- 设备端配置: 目标 Linux 设备可能需要在其引导加载程序或操作系统配置中启用串行控制台输出(例如,在树莓派的 /boot/config.txt 中添加 enable_uart=1 38)。
软件 (终端仿真器):
在主机上,需要使用终端仿真器软件来通过识别出的串行端口与设备通信。
- Windows:
- PuTTY: 是 Windows 上最流行和推荐的免费终端仿真器之一 5。
- 配置 PuTTY:
- 启动 PuTTY。
- 在 “Session” 类别中,选择连接类型为 “Serial” 5。
- 在 “Serial line” 输入框中,输入之前在设备管理器中识别出的 COM 端口名称(例如 COM5) 5。
- 在 “Speed (baud)” 输入框中,输入目标设备要求的波特率(例如 115200) 5。
- 导航到左侧面板的 “Connection” -> “Serial” 类别 5。
- 确认或设置以下参数:Data bits (通常为 8), Stop bits (通常为 1), Parity (通常为 None), Flow control (通常为 None) 5。
- 返回 “Session” 类别,可以在 “Saved Sessions” 下输入一个名称并点击 “Save” 来保存配置,方便以后使用 5。
- 点击 “Open” 按钮建立连接 5。连接成功后,您应该能看到来自设备的启动信息或登录提示符。
- Linux:
- Minicom: 是一个功能强大的串行通信程序 36。
- 安装: 通常使用包管理器安装,例如 sudo apt update && sudo apt install minicom 36。
- 配置: 运行 sudo minicom -s 进入配置菜单 45。
- 选择 “Serial port setup”。
- 按 ‘A’ 设置 “Serial Device” 为之前识别的设备文件路径(例如 /dev/ttyUSB0) 45。
- 按 ‘E’ 设置 “Bps/Par/Bits”(例如 115200 8N1 表示 115200 波特率, 8 数据位, 无校验, 1 停止位) 45。
- 按 ‘F’ 将 “Hardware Flow Control” 设置为 “No” 45。
- 按 ‘G’ 将 “Software Flow Control” 设置为 “No” 45。
- 按 Enter 返回主菜单。
- 选择 “Save setup as dfl” 将配置保存为默认值 45。
- 选择 “Exit from Minicom”。
- 启动: 运行 sudo minicom 45。
- 退出: 按 Ctrl+A,然后按 X 45。
- 权限: 可能需要将用户添加到 dialout 组 (sudo usermod -aG dialout $USER,然后重新登录) 才能访问串行端口而无需 sudo 5。
- Screen: 是一个更简单的终端多路复用器,也可用于串行连接 36。
- 安装: 通常预装,或 sudo apt install screen 37。
- 使用: sudo screen /dev/ttyUSB0 115200 (将设备路径和波特率替换为实际值) 36。
- 退出: 按 Ctrl+A,然后按 k,再按 y 确认。
- Minicom: 是一个功能强大的串行通信程序 36。
配置参数:
串行通信的成功依赖于主机和目标设备使用完全相同的通信参数。
常见串行通信参数
参数 (Parameter) | 描述 (Description) | 典型值 (Typical Values) |
---|---|---|
波特率 (Baud Rate) | 数据传输速率 (每秒信号单元数) 47 | 115200, 57600, 38400, 19200, 9600 40 (必须匹配设备) |
数据位 (Data Bits) | 每个字符的数据位数 48 | 8 5 |
校验位 (Parity) | 用于错误检测的附加位 48 | None (N) 5 |
停止位 (Stop Bits) | 指示字符结束的位数 48 | 1 5 |
流控制 (Flow Control) | 控制数据流以防止缓冲区溢出的机制 44 | None 5 (硬件流控制 RTS/CTS 有时也用,但通常禁用) |
- 查找设备设置: 正确的参数设置是设备特定的。通常可以在设备的官方文档、规格说明或相关的教程中找到 5。有时,如果能看到设备的引导加载程序(如 U-Boot)的输出,它可能会显示所使用的波特率。
故障排除:
- 无输出: 检查物理连接(TX/RX 是否接反?GND 是否连接?),确认设备已上电,确认主机选择了正确的 COM 端口或 /dev/tty* 设备,确认波特率设置正确,确认设备端已启用串行控制台输出,检查 USB 转串口适配器的驱动是否正确安装 38。
- 乱码: 最常见的原因是波特率不匹配 5。确保主机和设备的波特率设置完全一致。数据位、校验位或停止位设置错误也可能导致乱码。
- 权限错误 (Linux): 尝试使用 sudo 运行终端仿真器,或者将当前用户添加到 dialout 组 5。
- 驱动问题: 确保 USB 转串口适配器的驱动程序已在主机上正确安装 3。
1.3. 方法 2:通过 USB 网络访问
除了串行控制台,许多 Linux 设备可以通过 USB 数据线模拟一个网络接口,允许主机使用标准的网络协议(如 SSH, SCP, HTTP)与其通信。这种模式通常称为 USB Ethernet Gadget 模式 23。
概念:
当 Linux 设备启用 USB Ethernet Gadget 功能时(例如,通过加载 g_ether 内核模块 23),它会向通过 USB 连接的主机呈现为一个虚拟的网络适配器。主机操作系统会将其识别为一个标准的以太网接口(尽管是通过 USB 连接的),并为其分配一个网络接口名称(例如 Windows 上的 “USB Ethernet/RNDIS Gadget” 10 或 Linux 上的 usb0 23)。一旦主机和设备都在这个虚拟的 USB 网络链路上配置了兼容的 IP 地址,它们就可以像在普通以太网中一样进行通信,从而可以使用 SSH 进行远程登录、使用 SCP/SFTP 传输文件等 23。
这种方法比串行控制台提供了更丰富的功能,但配置也相对复杂,因为它涉及到网络层面的设置。
设备端设置 (Linux Gadget):
在目标 Linux 设备上启用 USB 网络功能通常需要:
- 内核支持: 内核必须编译了 USB Gadget 支持以及特定的 USB 网络功能驱动。
- 关键配置选项包括 CONFIG_USB_GADGET=y。
- 对于模拟以太网,需要 CONFIG_USB_ETH=m (或 =y) 23。
- 如果主机是 Windows,通常还需要 CONFIG_USB_ETH_RNDIS=y 以支持 RNDIS 协议 23。
- 网络协议栈支持也是必需的,例如 CONFIG_INET=y 23。
- 加载模块: 如果驱动是作为模块编译的,需要加载它。
- 例如,加载 g_ether 模块:modprobe g_ether [options] 23。
- 为了实现持久的网络标识,建议在加载模块时指定固定的 MAC 地址,例如:modprobe g_ether dev_addr=12:34:56:78:9a:bc host_addr=12:34:56:78:9a:bd 23。如果模块是内建的,这些参数可以通过内核命令行传递 (e.g., g_ether.dev_addr=…) 23。使用固定的 MAC 地址有助于主机系统始终将设备识别为同一个网络接口,避免每次连接都创建一个新的网络配置 33。
- 接口配置: 加载模块后,设备上会出现一个新的网络接口(通常是 usb0)。需要为其配置 IP 地址和子网掩码,并启用该接口。
- 使用 ip 命令 (推荐):
Bash
ip addr add 192.168.7.2/24 dev usb0
ip link set usb0 up
23 (IP 地址 192.168.7.2 和子网 /24 仅为示例)。 - 使用 ifconfig 命令 (旧版):
Bash
ifconfig usb0 192.168.7.2 netmask 255.255.255.0 up
23。
- 使用 ip 命令 (推荐):
主机端设置:
主机也需要进行配置才能与通过 USB 连接的 Linux 设备进行网络通信。
- 驱动安装 (Windows): Windows 可能需要安装特定的驱动程序才能识别 Linux 设备模拟的网络适配器,特别是 RNDIS 设备 23。这些驱动有时包含在设备提供的虚拟 U 盘中(如 BeagleBone Black 53),或者需要从设备制造商或芯片供应商处下载。安装后,设备应出现在设备管理器的“网络适配器”下 9。
- 接口配置: 主机需要为其端的 USB 网络接口配置一个 IP 地址,该地址必须与设备端的 IP 地址位于同一子网内,但地址本身不能冲突 23。
- Windows: 通过“网络连接”(或“网络和共享中心” -> “更改适配器设置”)找到对应的 USB 网络适配器,右键单击选择“属性”,然后配置 TCP/IPv4 设置,为其分配一个静态 IP 地址(例如 192.168.7.1)和子网掩码(例如 255.255.255.0) 8。
- Linux: 使用 ip 或 ifconfig 命令为在主机上识别出的对应接口(可能是 usb0 或其他名称 29)配置 IP 地址和子网掩码,并启用接口。
Bash
# 例如,如果主机接口是 enp0s26u1u1
sudo ip addr add 192.168.7.1/24 dev enp0s26u1u1
sudo ip link set enp0s26u1u1 up
23。
IP 地址发现/分配:
在点对点的 USB 网络连接中,如何分配 IP 地址是一个关键问题。
- 静态 IP: 这是最简单和最可靠的方法,尤其适用于直接连接的调试场景 23。手动为设备端(例如 192.168.7.2)和主机端(例如 192.168.7.1)分配同一子网内的固定 IP 地址。这样可以确保每次连接时地址都是已知的。常用的私有地址段包括 192.168.x.y 或 10.x.y.z 28。
- DHCP: 理论上,可以让其中一端(主机或设备)运行 DHCP 服务器来为另一端分配 IP 地址 31。例如,主机可以通过“Internet 连接共享”功能为 USB 设备分配 IP 34,或者设备本身可以运行 dnsmasq 等 DHCP 服务器软件 34。然而,在简单的双机直连场景下,设置 DHCP 服务器会增加不必要的复杂性 33。如果使用了 DHCP,需要检查 DHCP 服务器的租约列表或在客户端上使用 ip addr 或 ipconfig 来查找分配到的 IP 地址 31。
- 链路本地地址/Zeroconf/Avahi:
- IPv4 链路本地地址 (APIPA): 当设备配置为 DHCP 但无法找到 DHCP 服务器时,它们可能会根据 RFC 3927 自动分配一个 169.254.x.y 范围内的 IP 地址 34。这允许在没有手动配置或 DHCP 服务器的情况下进行本地网络通信。
- Zeroconf (Avahi/Bonjour): Zeroconf 协议(在 Linux 上通常由 Avahi 实现 30,在 macOS/Windows 上称为 Bonjour)建立在链路本地地址之上,增加了主机名发现功能。设备可以广播其主机名(例如 raspberrypi.local),其他支持 Zeroconf 的机器可以通过这个 .local 名称来解析其 IP 地址,而无需知道具体的 IP 29。可以使用 avahi-autoipd 来获取链路本地地址 52,使用 avahi-browse 30 或 avahi-discover 34 来发现网络上的服务和主机。
- 挑战: Zeroconf 并非总是可靠,尤其是在跨平台环境中 29。它依赖于两端都运行并正确配置了相应的服务(如 avahi-daemon 30)。如果网络中存在多个 Zeroconf 设备,可能会出现路由问题 55。
- IPv6 链路本地地址: IPv6 也支持链路本地地址(fe80:: 开头),并且通常是自动配置的。有时可以通过 IPv6 链路本地地址进行连接,但可能需要在地址后面指定接口名称(范围 ID),例如 ssh -6 pi@fe80::9469:84c0:ec07:4d1e%enp0s26u1u1u3 30。
建立 SSH 连接:
一旦网络配置完成并且设备和主机可以相互通信(可以通过 ping <device_ip_address> 11 来测试),就可以尝试通过 SSH 连接到 Linux 设备。
- 检查设备上的 SSH 服务器: 确保 SSH 服务器守护进程(通常是 sshd)正在目标 Linux 设备上运行。
- 使用 systemctl status sshd (对于使用 systemd 的系统) 60 或 service sshd status (对于较旧的系统) 60 来检查服务状态。
- 如果服务未运行,使用 sudo systemctl start sshd 或 sudo service sshd start 启动它 50。
- 使用 sudo systemctl enable sshd 或相应命令确保 SSH 服务在系统启动时自动运行 60。
- 检查设备上的防火墙设置(如 ufw 或 iptables),确保 SSH 端口(默认为 22)允许入站连接 50。例如,使用 sudo ufw status 检查 ufw 规则 60。
- 从主机连接: 在主机上打开终端或命令提示符,使用 SSH 客户端命令进行连接。
- 基本语法:ssh <username>@<device_ip_address> 49。将 <username> 替换为设备上的有效用户名,将 <device_ip_address> 替换为设备的 IP 地址(静态配置的、DHCP 分配的或通过 Zeroconf 解析的)。
- 首次连接: 第一次连接到某个主机时,SSH 客户端会显示该主机的公钥指纹,并询问是否信任该主机。输入 yes 并按 Enter 键,该主机的密钥将被添加到主机的 ~/.ssh/known_hosts 文件中,后续连接将不再提示 49。
- 密码提示: 之后,系统会提示输入设备上用户的密码。输入密码(输入时通常不显示)并按 Enter 键 49。
- 连接成功后,您将看到设备上的 shell 提示符,表示已通过 SSH 成功登录。
故障排除:
- 连接性问题: 使用 ping <device_ip> 从主机测试到设备的基本网络连接 11。如果 ping 不通,检查:
- 两端的 IP 地址和子网掩码是否配置正确且在同一子网内 11。
- 两端的网络接口是否都已启用 (UP 状态) 25。
- 物理 USB 连接是否稳定。
- 设备或主机上的防火墙是否阻止了 ICMP (ping) 请求或响应。
- 驱动程序问题 (Windows): 确保 Windows 已正确识别 USB 网络适配器并安装了合适的 RNDIS 或 CDC Ethernet 驱动 23。检查设备管理器中是否有未知设备或带有黄色感叹号的网络适配器 4。
- SSH 问题:
- Connection Refused: 通常表示目标设备上的 SSH 服务器未运行或防火墙阻止了端口 22 的连接 50。
- Permission Denied / Authentication Failed: 用户名或密码错误。或者,如果使用 SSH 密钥,请确保密钥对配置正确。
- Timeout: 网络连接不稳定,或者路由配置错误,或者防火墙阻止了 SSH 连接。
- Zeroconf 问题: .local 名称无法解析 29。确保两端都运行了 Avahi/Bonjour 服务,并且防火墙允许 mDNS (UDP 端口 5353) 通信。尝试使用 avahi-browse -art 30 或类似工具在主机上查找设备。
网络复杂性权衡:
选择串行控制台还是 USB 网络连接取决于调试任务的需求。串行连接在概念上更简单,只需要匹配基本的通信参数(波特率、数据位等) 5,并且通常在系统启动早期或网络完全失效时也能工作。然而,它的功能有限,主要用于文本控制台交互。
相比之下,USB 网络连接提供了更强大的功能,允许使用 SSH 进行安全的远程 shell 访问、使用 SCP/SFTP 进行文件传输,甚至可能运行基于网络的应用程序或服务 23。但是,这种强大功能的代价是增加了配置的复杂性。它引入了标准的网络概念,如 IP 地址、子网掩码、路由、DHCP、DNS 和防火墙规则 23。成功建立连接需要确保两端都进行了正确的网络配置 23,并且引入了更多的潜在故障点,例如 IP 地址冲突、路由问题、DHCP 服务器故障或 Zeroconf 的不可靠性 11。
因此,当只需要基本的控制台访问,尤其是在引导过程或网络故障期间进行调试时,串行连接是首选。当需要进行更复杂的操作,如传输文件、运行需要网络连接的调试工具或访问图形界面(如果设备支持通过网络转发)时,USB 网络连接的额外配置复杂性是值得的。
第 2 节:基础调试技术
一旦通过串行控制台或 SSH 建立了与 Linux 设备的连接,就可以利用 Linux 强大的命令行工具集来监控系统状态、分析日志、跟踪程序行为和调试应用程序。本节将介绍一些最基础且常用的调试技术。
2.1. 监控系统进程和性能
了解系统中正在运行哪些进程、它们消耗多少资源(CPU、内存)以及它们的状态(运行、睡眠、僵尸等)对于识别性能瓶颈、查找失控的应用程序或诊断系统缓慢至关重要。
- ps (Process Status):
- 用途: ps 命令提供系统在某个时间点的进程快照 64。它对于查看当前运行的进程列表或在脚本中获取特定进程信息非常有用。
- 常用法:
- ps aux 或 ps -ef: 显示所有用户的所有进程的详细信息 64。aux (BSD 风格) 和 -ef (System V 风格) 提供的信息类似但格式略有不同。
- 关键列解释:
- USER: 进程所有者 64。
- PID: 进程 ID 64。
- %CPU: 进程使用的 CPU 百分比 (通常是进程生命周期内的平均值) 64。
- %MEM: 进程使用的物理内存百分比 64。
- VSZ: 虚拟内存大小。
- RSS: 常驻集大小 (物理内存占用)。
- TTY: 控制终端 64。
- STAT 或 S: 进程状态 (如 R-运行, S-睡眠, Z-僵尸, T-停止)。
- START: 进程启动时间。
- TIME: 进程累计使用的 CPU 时间 64。
- COMMAND 或 CMD: 启动进程的命令 64。
- 过滤与排序:
- 按用户过滤: ps -u <username> 64。
- 按 PID 过滤: ps -p <pid> 64。
- 按 CPU 或内存使用排序: ps aux --sort=-%cpu 或 ps aux --sort=-%mem 64。
- 自定义输出格式: ps -eo pid,ppid,cmd,%cpu,%mem --sort=-%cpu (显示特定列并按 CPU 排序) 64。
- top:
- 用途: top 命令提供一个实时、动态、交互式的系统进程视图 64。它非常适合持续监控系统负载和识别当前资源消耗最高的进程。
- 界面:
- 摘要区 (上半部分): 显示系统总体信息,如系统时间、运行时间、登录用户数、平均负载 (1, 5, 15 分钟)、任务总数 (运行、睡眠、停止、僵尸)、CPU 使用率 (用户、系统、空闲等)、内存和交换空间使用情况 64。
- 进程列表 (下半部分): 实时更新的进程列表,默认按 CPU 使用率排序。包含的列类似于 ps,如 PID, USER, PR (优先级), NI (Nice 值), VIRT (虚拟内存), RES (常驻内存), SHR (共享内存), S (状态), %CPU, %MEM, TIME+ (累计 CPU 时间), COMMAND 64。
- 交互式命令: 在 top 运行时,可以按特定键进行交互:
- h 或 ?: 显示帮助 65。
- k: 杀死一个进程 (会提示输入 PID 和信号,默认为 SIGTERM(15),强制杀死用 SIGKILL(9)) 66。
- r: 重新设置进程的 nice 值 (优先级)。
- u: 按用户过滤进程。
- M: 按内存使用排序。
- P: 按 CPU 使用排序 (默认)。
- q: 退出 top。
- 刷新: 默认情况下,top 每隔几秒刷新一次 64。
- htop:
- 用途: htop 是 top 的一个增强版本,提供了更友好、更强大的交互式界面 64。
- 特性:
- 彩色显示: 更易于阅读 64。
- 鼠标支持: 可以使用鼠标滚动列表、选择进程、点击进行操作 64。
- 树状视图: 可以按 F5 或 -t 选项启动,清晰地显示进程间的父子关系 64。
- 更易管理: 可以直接选中进程按 F9 (或 k) 发送信号,无需手动输入 PID 64。
- 可定制: 可以通过 F2 (Setup) 自定义显示的列、颜色方案等。
- 多核 CPU 显示: 在顶部清晰显示每个 CPU 核心的使用率 64。
- 启动选项:
- htop -u <username>: 只显示特定用户的进程 64。
- htop -p <pid1>,<pid2>: 只显示特定 PID 的进程 64。
- htop -t: 以树状视图启动 64。
进程监控工具比较 (ps vs. top vs. htop)
特性 (Feature) | ps | top | htop |
---|---|---|---|
模式 (Mode) | 快照 (Snapshot) 65 | 实时、动态 (Real-time, Dynamic) 65 | 实时、动态 (Real-time, Dynamic) 64 |
交互性 (Interactivity) | 低 (主要用于非交互式) 65 | 中 (键盘命令) 64 | 高 (键盘 + 鼠标) 64 |
界面 (UI) | 纯文本输出 | 文本界面,分上下两区 64 | 彩色文本界面,更直观 64 |
主要功能 (Key Features) | 进程列表、过滤、排序、自定义输出 64 | 实时监控、按资源排序、基本进程管理 64 | 实时监控、高级排序/过滤、树状视图、易用进程管理 64 |
资源消耗 (Resource Usage) | 低 | 中 | 中 |
典型用途 (Use Cases) | 脚本、获取特定信息、一次性查看 65 | 持续监控系统负载、识别资源消耗大户 65 | 交互式探索进程、详细分析、易用的进程管理 64 |
解读输出:
- 高 CPU/内存使用: 持续占用高百分比 CPU 或内存的进程可能是性能瓶颈的原因。
- 僵尸进程 (Zombie, Z): 已完成执行但其父进程尚未读取其退出状态的进程。少量僵尸进程通常无害,但大量僵尸进程可能表明父进程存在问题。
- I/O 等待 (Wait, wa - 在 top/htop CPU 状态中): CPU 等待磁盘或网络 I/O 操作完成的时间百分比。高 I/O 等待通常表示存储或网络瓶颈。
- 平均负载 (Load Average - 在 top/htop 摘要中): 系统在过去 1、5、15 分钟内的平均负载。数值大致表示等待 CPU 或处于不可中断 I/O 等待的进程数。如果该值持续高于 CPU 核心数,则系统可能过载。
2.2. 分析系统日志和内核消息
日志文件记录了系统运行过程中的各种事件、错误和状态信息,是诊断问题(尤其是崩溃、启动失败或间歇性故障)不可或缺的工具 16。Linux 系统通常有多个日志来源。
- 内核环形缓冲区 (dmesg):
- 用途: dmesg 用于显示和控制内核环形缓冲区的内容 16。这个缓冲区存储了内核启动过程中的消息,以及关于硬件检测、驱动程序初始化和内核模块加载/卸载的实时事件 16。它是诊断硬件相关问题或早期启动问题的首选工具 16。
- 使用方法:
- 直接运行 dmesg 会输出整个缓冲区 16。由于输出可能很长,通常需要配合管道和分页工具使用,如 dmesg | less 16。
- 过滤: 使用 grep 按关键字过滤非常有用,例如:
- dmesg | grep -i usb (查找 USB 相关消息) 17
- dmesg | grep -i tty (查找 TTY/串口相关消息) 16
- dmesg | grep -i eth 或 dmesg | grep -i net (查找网络接口相关消息) 16
- dmesg | grep -i error 或 dmesg | grep -i fail (查找错误或失败信息) 19
- dmesg | grep -i sda (查找磁盘相关消息,sda 通常是第一个 SATA/SCSI/USB 磁盘) 16
- dmesg | grep -E “memory|dma” (使用扩展正则表达式搜索多个词) 16
- 时间戳:
- -T: 显示人类可读的时间戳 (例如 [Mon Oct 14 14:38:04 2019]) 17。这对于关联事件发生的时间非常重要。
- –time-format <format>: 指定时间戳格式,如 iso, ctime, delta 16。
- 实时监控: dmesg -w 或 dmesg --follow 可以持续显示新产生的内核消息,适合实时监控硬件事件或驱动行为 16。
- 着色与可读性: -L 强制着色输出 16,-H 提供人类可读输出并自动分页 17。
- 按级别/设施过滤:
- -l <level>: 按严重性级别过滤 (如 emerg, alert, crit, err, warn, notice, info, debug) 16。例如 dmesg -l err,warn 只显示错误和警告。
- -f <facility>: 按消息来源设施过滤 (如 kern, user, daemon, syslog) 16。
- -x: 同时显示级别和设施信息 16。
- 清除缓冲区: sudo dmesg -C 可以清除内核环形缓冲区的内容 (需要 root 权限) 17。
- 内核日志级别: 内核消息有不同的严重级别,从 KERN_EMERG (系统不可用) 到 KERN_DEBUG (调试信息) 18。dmesg 默认显示的级别可以通过内核参数 console_loglevel 控制 18。
- Systemd 日志 (journalctl):
- 用途: 在使用 Systemd 作为初始化系统的现代 Linux 发行版 (如较新的 Debian, Ubuntu, CentOS, Fedora) 上,journalctl 是查询和管理系统日志的主要工具 67。它集中管理来自内核、系统服务、引导过程和应用程序的日志,并以结构化的二进制格式存储,支持强大的过滤功能 71。
- 基本用法:
- journalctl: 显示所有日志,从最旧的开始 70。默认会使用分页器 (如 less)。
- journalctl -r: 反向显示日志,最新的在最前面 67。
- journalctl -n <N>: 显示最后 N 条日志 (默认 N=10) 70。
- journalctl -f: 实时跟踪新日志 (类似 tail -f) 71。
- 过滤: journalctl 提供了丰富的过滤选项:
journalctl 常用过滤选项
选项 (Option) | 描述 (Description) | 示例 (Example) |
---|---|---|
-b [<offset>] | 按启动次数过滤 (0=当前, -1=上一次,…) 70 | journalctl -b (当前启动) <br> journalctl -b -1 (上一次启动) |
–since <time> | 显示指定时间之后的日志 67 | journalctl --since “2023-10-26 18:00:00” <br> journalctl --since yesterday |
–until <time> | 显示指定时间之前的日志 67 | journalctl --until “1 hour ago” |
-u <unit_name> | 按 Systemd 单元 (服务) 名称过滤 67 | journalctl -u sshd.service |
-p <priority> | 按优先级过滤 (0=emerg 到 7=debug, 或名称如 err) 67 | journalctl -p err (错误及以上级别) <br> journalctl -p 3 (同上) |
-k | 只显示内核消息 (同 dmesg) 70 | journalctl -k |
-g <pattern>, --grep | 按消息内容过滤 (支持正则表达式) 71 | `journalctl -g "failed\ |
_PID=<N> | 按进程 ID 过滤 71 | journalctl _PID=1234 |
_SYSTEMD_UNIT=<unit> | 按 Systemd 单元过滤 (更通用的字段匹配) 72 | journalctl _SYSTEMD_UNIT=nginx.service |
* **输出格式:** `-o <format>` 可以改变输出格式,例如 `-o json` (JSON 格式), `-o json-pretty` (美化的 JSON), `-o short` (类似传统 syslog), `-o cat` (只显示消息本身) [71, 72]。
* **权限:** 默认情况下,普通用户只能看到自己进程的日志。要查看所有系统日志,用户需要被添加到特定组,如 `adm` 或 `systemd-journal` [67]。
* **存储:** 日志通常存储在 `/var/log/journal/` 目录下 [71]。可以使用 `journalctl --disk-usage` 查看磁盘占用情况,并使用 `–vacuum-size=`, `–vacuum-time=`, `–vacuum-files=` 来清理旧日志 [67, 71]。默认情况下,日志可能配置为非持久化(只在内存中),需要特定配置才能确保存储到磁盘并在重启后保留 [71]。
- 传统日志文件 (/var/log):
- 位置: 许多应用程序和服务仍然遵循传统的日志记录方式,将日志文件存储在 /var/log 目录及其子目录中 68。
- 常见文件:
- /var/log/syslog (Debian/Ubuntu) 或 /var/log/messages (RHEL/CentOS): 包含系统范围内的通用消息,包括来自内核、守护进程、认证等的消息 69。
- /var/log/auth.log (Debian/Ubuntu) 或 /var/log/secure (RHEL/CentOS): 包含认证相关的日志,如用户登录成功/失败、sudo 使用记录等 69。
- /var/log/kern.log: 主要包含内核消息 69。
- /var/log/dmesg: 通常是 dmesg 命令输出的快照 69。
- /var/log/cron: cron 守护进程(用于执行计划任务)的日志 69。
- /var/log/maillog 或 /var/log/mail.log: 邮件服务器 (如 Postfix, Sendmail) 的日志 69。
- 应用程序日志: 许多应用程序(如 Apache, Nginx, MySQL, PostgreSQL)会在 /var/log 下创建自己的子目录来存放日志文件,例如 /var/log/apache2/access.log, /var/log/mysql/error.log 69。
- 二进制日志: /var/log/wtmp (用户登录/注销历史) 和 /var/log/lastlog (用户最后登录信息) 是二进制文件,需要使用特定命令如 last 和 lastlog 来查看 73。utmp (当前登录用户) 通常在 /var/run/utmp 或 /run/utmp,使用 who 或 w 查看 74。
- 查看工具: 由于这些通常是纯文本文件,可以使用标准的 Linux 文本处理工具查看:
- cat <file>: 显示整个文件内容 68。适用于小文件。
- less <file>: 分页查看文件,支持前后滚动和搜索 68。适用于大文件。
- tail <file>: 显示文件末尾内容 (默认 10 行) 68。
- tail -f <file>: 实时跟踪文件末尾的新增内容,非常适合监控活动日志 68。
- head <file>: 显示文件开头内容 (默认 10 行) 68。
- grep <pattern> <file>: 在文件中搜索特定模式或文本 68。例如 grep -i error /var/log/syslog。
- 日志轮替 (Log Rotation): 为了防止日志文件无限增长并耗尽磁盘空间,系统通常使用 logrotate 工具定期对日志文件进行轮替(压缩、重命名、删除旧文件)。logrotate 的配置通常在 /etc/logrotate.conf 和 /etc/logrotate.d/ 目录下的文件中定义 68。
关联不同来源的日志:
系统问题往往不是孤立的,一个根本原因可能会在不同地方留下痕迹。例如,一个磁盘硬件故障可能首先在 dmesg 中记录 I/O 错误 16,随后导致数据库服务(如 MySQL)失败,这会在 journalctl -u mysql.service 或 /var/log/mysql/error.log 中留下记录 69,最终导致依赖该数据库的 Web 应用程序在 /var/log/apache2/error.log 中报告错误 73。
有效的调试通常需要检查来自多个来源的日志(dmesg, journalctl, 相关服务的 /var/log 文件),并利用时间戳将不同日志中的事件关联起来 16。dmesg -T 17 和 journalctl 67 默认提供带日期和时间的时间戳,而传统日志文件通常也在每行开头包含时间戳 68。通过比对这些时间戳,可以重建事件发生的时间线,从而更好地理解问题的根本原因和影响范围。
2.3. 跟踪应用程序系统调用 (strace)
strace 是一个强大的诊断和调试工具,它可以拦截并记录目标进程进行的系统调用 (System Calls) 以及该进程接收到的信号 (Signals) 75。系统调用是用户空间程序请求内核执行特权操作(如文件读写、网络通信、进程创建等)的接口。
用途:
strace 对于理解程序如何与操作系统内核交互至关重要 75。它特别适用于以下场景:
- 调试无源码程序: 当你没有程序的源代码时,strace 可以揭示其底层行为 75。
- 诊断系统交互问题: 找出程序失败的原因是否在于文件权限、网络连接、无效参数传递给系统调用等 76。
- 性能分析: 识别程序中过于频繁或耗时过长的系统调用。
- 理解程序行为: 观察程序实际打开了哪些文件、连接了哪些网络地址等。
基本用法:
- 启动并跟踪新进程:
Bash
strace <command> [arguments…]
例如: strace ls -l /tmp 75 或 strace python my_script.py 75。strace 会启动指定的命令,并将其进行的系统调用输出到标准错误 (stderr)。 - 附加到已运行进程:
Bash
strace -p <PID>
78。首先需要使用 ps 或 pgrep 找到目标进程的 PID。strace 会附加到该进程并开始跟踪其系统调用。按 Ctrl+C 可以分离 strace 并停止跟踪,目标进程会继续运行 80。
关键选项:
strace 提供了许多选项来控制其行为和输出。
strace 常用选项
选项 (Option) | 描述 (Description) |
---|---|
-p <PID> | 附加到指定的进程 ID 78 |
-f | 跟踪由 fork(), vfork(), clone() 创建的子进程 81 |
-ff | 与 -o <filename> 结合使用,将每个进程/线程的跟踪输出写入单独的文件 filename.<pid> 81 |
-e trace=<set> | 只跟踪指定的系统调用集合。集合可以是具体的系统调用名称 (逗号分隔),或预定义的类别,如 file (文件操作), network (网络), signal (信号), ipc (进程间通信), desc (文件描述符), memory (内存映射) 75 |
-e signal=<set> | 只跟踪指定的信号。 |
-o <filename> | 将跟踪输出写入指定文件,而不是 stderr 76 |
-c | 在程序退出时,统计每个系统调用的耗时、调用次数和错误次数,并生成摘要报告 75 |
-t, -tt, -ttt | 在每行输出前加上时间戳 (精度递增) 76 |
-r | 打印每个系统调用相对于上一个系统调用开始的时间差 76 |
-T | 显示每个系统调用花费的时间 76 |
-s <strsize> | 指定打印字符串的最大长度 (默认为 32)。对于查看完整路径名或网络缓冲区内容,通常需要增大此值,例如 -s 1024 79 |
-i | 打印执行系统调用时的指令指针 (instruction pointer) 76 |
解读输出:
strace 的输出通常遵循以下格式:
syscall_name(arg1, arg2,…) = return_value
- syscall_name: 系统调用的名称 (如 openat, read, write, socket, connect) 75。
- arg1, arg2,…: 传递给系统调用的参数。strace 会尝试以有意义的方式显示它们(例如,文件名、标志位、内存地址)。
- return_value: 系统调用的返回值。通常,成功时返回 0 或正数(如文件描述符),失败时返回 -1 76。
- ``: 如果系统调用失败 (返回 -1),strace 会显示错误码的符号名称 (如 ENOENT, EPERM, EACCES) 和对应的错误描述 (如 “No such file or directory”, “Operation not permitted”, “Permission denied”) 75。
示例:
- openat(AT_FDCWD, “/etc/passwd”, O_RDONLY) = 3 (成功打开文件 /etc/passwd,返回文件描述符 3)
- read(3, “root❌0:0:root:/root:/bin/bash\n”…, 4096) = 1024 (从文件描述符 3 读取了 1024 字节)
- write(1, “Hello\n”, 6) = 6 (向文件描述符 1 (stdout) 写入了 6 字节)
- access(“/data/myfile”, W_OK) = -1 EACCES (Permission denied) (尝试检查写权限失败,因为权限不足)
- clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|…) = 12345 (创建了一个子进程,返回子进程的 PID) 82
揭示隐藏的交互:
程序源代码中的一个简单操作,在底层可能会转化为多个复杂的系统调用。例如,一个简单的打印语句 print(“Hello”) 在 Python 中,可能涉及到 write() 系统调用将字符串输出到标准输出 75。文件操作库函数可能会先调用 access() 检查权限,再调用 openat() 打开文件。网络库函数会调用 socket(), connect(), sendto(), recvfrom() 等一系列系统调用。
strace 的价值在于它能揭示这些隐藏在库函数或高级语言结构之下的底层交互 75。当程序行为不符合预期时,strace 可以帮助我们看到实际发生了什么:程序是否尝试访问了错误的路径?是否因为权限问题而失败?网络连接是否被拒绝?这些信息对于定位问题的根源非常有价值,尤其是在调试复杂的、依赖系统资源的应用程序时。
注意: 启用 strace 会显著降低被跟踪进程的运行速度,因为它需要在每次系统调用进入和退出时都中断进程 80。因此,它主要用于调试,不应在生产环境中持续运行。
2.4. 使用 GDB 调试应用程序
GDB (GNU Project Debugger) 是 Linux 环境下标准的、功能强大的交互式源代码级调试器,主要用于 C 和 C++ 程序,但也支持其他语言 89。它允许开发者在程序运行时进行深入检查和控制。
用途:
GDB 主要用于:
- 查找和定位 Bug: 如段错误 (segmentation faults)、逻辑错误、内存泄漏等。
- 理解程序流程: 通过单步执行代码,观察程序执行路径。
- 检查程序状态: 在特定点暂停程序,查看变量的值、内存内容、调用栈等 89。
- 动态修改: 在调试过程中修改变量值,测试不同场景 90。
准备工作:
- 使用 -g 编译: 为了让 GDB 能够关联可执行文件中的指令与源代码行、变量名等信息,必须在编译时使用 -g 选项 89。
Bash
gcc -g -o my_program my_program.c
g++ -g -o my_app my_app.cpp
没有 -g 选项编译的程序,GDB 仍然可以运行,但调试信息会非常有限,无法有效地进行源代码级调试。
启动 GDB:
- 调试新程序:
Bash
gdb./my_program
90。这将加载程序及其调试符号,并显示 GDB 提示符 (gdb)。 - 附加到已运行进程:
Bash
gdb --pid <PID>
78。首先使用 ps 或 pgrep 获取目标进程的 PID。GDB 会暂停该进程并允许你进行调试。
核心命令:
GDB 拥有众多命令,以下是一些最基础和常用的命令:
GDB 核心命令
命令 (Command) | 缩写 (Abbreviation) | 描述 (Description) |
---|---|---|
run [args…] | r | 开始执行已加载的程序。可以提供命令行参数 89。 |
break <location> | b | 在指定位置设置断点。位置可以是函数名 (main), 文件名:行号 (myfile.c:25), 或内存地址 (*0x4005a0) 89。 |
info breakpoints | info b | 列出当前设置的所有断点及其编号和状态 89。 |
delete <num> | d <num> | 删除指定编号的断点 89。不带编号则删除所有断点。 |
clear <location> | 清除指定位置的断点 89。 | |
enable <num> / disable <num> | 启用或禁用指定编号的断点 90。 | |
continue | c | 从当前停止点恢复程序执行,直到遇到下一个断点、程序结束或发生错误 89。 |
step | s | 执行下一行源代码。如果当前行包含函数调用,则进入该函数内部 89。 |
next | n | 执行下一行源代码。如果当前行包含函数调用,则执行完整个函数(步过),停在函数调用后的下一行 89。 |
until [<location>] | u | 继续执行直到程序到达当前栈帧中比当前行号更大的行号,或者到达指定位置。用于跳出循环 89。 |
list [<location>] | l | 显示当前行附近的源代码。可以指定位置(行号、函数名) 89。 |
print <expression> | p | 计算并打印表达式的值。表达式可以是变量名、指针解引用、数组元素、结构成员等。p array@10 打印数组前 10 个元素 89。 |
set var <variable>=<value> | 在程序执行期间修改变量的值 90。 | |
backtrace | bt | 显示当前的函数调用栈(调用链)。对于分析程序崩溃位置或理解当前执行点如何到达非常有用 78。 |
quit | q | 退出 GDB 89。 |
help [<command>] | h | 显示 GDB 的帮助信息,可指定命令获取详细帮助 89。 |
调试流程示例:
- 编译: gcc -g -o my_buggy_program my_buggy_program.c
- 启动 GDB: gdb./my_buggy_program
- 设置断点: (gdb) break main
- 运行程序: (gdb) run (程序会在 main 函数入口处停止)
- 单步执行: 使用 next 或 step 逐行执行代码。
- 检查变量: (gdb) print my_variable
- 继续执行: (gdb) continue (直到下一个断点或结束)
- (如果程序崩溃) 运行程序,崩溃后 GDB 会停在出错点。
- 查看调用栈: (gdb) backtrace (找出崩溃发生在哪个函数调用链中)
- 退出: (gdb) quit
GDB 是 C/C++ 开发者在 Linux 环境下进行调试的基础工具,熟练掌握其核心命令对于提高开发效率和解决复杂问题至关重要。
第 3 节:高级内核调试概述
当问题发生在 Linux 内核本身,例如驱动程序错误、内核模块崩溃或难以追踪的系统性能问题时,用户空间的调试工具(如 strace 和 gdb)可能不足以诊断问题。这时需要使用专门的内核调试技术。本节简要介绍两种主要的内核调试工具:KGDB 和 Ftrace。这些工具通常需要特定的内核配置和更复杂的设置。
3.1. KGDB 简介 (Kernel GNU Debugger)
用途:
KGDB 允许开发者使用熟悉的 GDB 界面对正在运行的 Linux 内核进行源代码级的调试 77。它使得开发者能够像调试普通应用程序一样,在内核代码中设置断点、单步执行、检查变量和内存、查看调用栈等 77。
工作原理与设置:
KGDB 采用远程调试模式,需要两台机器协同工作 77:
- 目标机 (Target Machine): 运行待调试的 Linux 内核。该内核必须在编译时启用了 KGDB 支持和相关的 I/O 驱动(如串口或以太网),并且通常需要包含调试信息 (CONFIG_DEBUG_INFO) 77。
- 主机 (Host Machine): 运行 GDB 客户端。开发者在此机器上加载目标内核的 vmlinux 文件(包含符号信息,注意不是压缩的启动镜像如 zImage 或 uImage 94),并通过指定的连接方式(通常是串口)连接到目标机上的 KGDB stub。
连接方式:
- 串口 (Serial Port): 这是最常用的连接方式,通过 kgdboc (KGDB over Console) 驱动实现 93。需要在目标机的内核启动参数中指定串口设备和波特率,例如 kgdboc=ttyS0,115200 93。
- kgdbwait 参数: 在内核启动参数中添加 kgdbwait (必须放在 kgdboc 参数之后) 会使内核在启动早期、KGDB I/O 驱动初始化后暂停,等待 GDB 客户端从主机连接 93。这对于调试早期启动过程中的问题非常有用。
- 其他方式: 理论上也支持通过以太网或 Firewire 连接,但串口更为常见和可靠 95。
使用场景:
- 调试内核模块或设备驱动程序中的复杂逻辑错误。
- 分析内核数据结构和状态。
- 跟踪难以通过日志或 ftrace 复现的内核 Bug。
- 当需要交互式地探索内核执行流程时。
局限性:
- 侵入性: KGDB 需要暂停整个内核的执行来进行调试,这对于需要实时响应的系统可能是不可接受的 77。
- 依赖性: KGDB 本身的运行依赖于内核的部分功能(如中断处理、串口驱动)正常工作。如果这些部分出现问题,或者内核发生严重崩溃 (Panic),KGDB 连接可能会中断或无法建立 77。
- 设置复杂: 需要重新编译内核,配置启动参数,并设置两台机器之间的物理连接。
- 早期启动/Panic 限制: 对于非常早期的启动问题或导致通信中断的内核 Panic,KGDB 的作用有限 77。
与 KDB 对比: KDB (Kernel DeBugger) 是一个内建的、基于控制台的内核调试器,不需要远程连接 77。它提供了一个简单的命令行界面,可以检查内存、寄存器、进程列表、设置断点等,但不是源代码级的调试器 93。KDB 更轻量级,有时在 KGDB 无法使用时(如没有第二台机器或串口)可以提供一些基本的诊断信息。某些配置下可以在 KDB 和 KGDB 之间切换 93。
3.2. Ftrace 简介 (Function Tracer)
用途:
Ftrace 是 Linux 内核内置的一个强大的跟踪框架,旨在帮助开发者理解内核内部的执行流程和性能特征,而无需停止内核运行 96。它不是一个像 GDB 那样的交互式调试器,而是一个观察工具。
Ftrace 可以跟踪:
- 函数调用: 记录内核函数的进入和退出 96。
- 内核事件: 利用内核中预设的静态跟踪点 (tracepoints) 来记录特定事件的发生,如调度切换、系统调用、中断、磁盘 I/O 等 96。
- 延迟: 测量关键路径的延迟,例如中断禁用时间、抢占禁用时间、任务唤醒到实际运行的延迟等 96。
工作原理与接口:
- Ftrace 通过内核编译时插入的探测点(或动态修改代码,如果 CONFIG_DYNAMIC_FTRACE 启用 99)来捕获信息。
- 用户主要通过 tracefs 虚拟文件系统与 Ftrace 交互,该文件系统通常挂载在 /sys/kernel/tracing (较新内核) 或 /sys/kernel/debug/tracing (较旧内核) 96。
关键文件/概念:
- available_tracers: 列出内核支持的跟踪器类型 (e.g., nop, function, function_graph, irqsoff, preemptoff, wakeup, sched_switch) 96。nop 表示不进行跟踪。
- current_tracer: 读取或写入此文件来查看或设置当前活动的跟踪器。例如 echo function_graph > current_tracer 96。
- tracing_on: 控制是否将跟踪数据写入环形缓冲区。echo 1 > tracing_on 启用记录,echo 0 > tracing_on 禁用记录(但跟踪本身可能仍在后台进行) 96。
- trace: 读取此文件可获取跟踪缓冲区内容的快照。读取时会暂停记录 96。写入此文件(如 echo > trace)会清空缓冲区 98。
- trace_pipe: 以流式方式读取跟踪数据,读取过的数据会被消耗掉。适合实时观察跟踪输出,且读取时不会暂停记录 96。
- set_ftrace_filter: 允许指定只跟踪特定的函数(支持通配符) 99。
- set_graph_function: 类似于 set_ftrace_filter,但用于 function_graph 跟踪器 99。
- events/: 这个目录下包含了按子系统组织的各种内核事件(静态跟踪点)。可以通过向对应事件目录下的 enable 文件写入 1 或 0 来启用或禁用特定事件的跟踪 96。
使用场景:
- 性能分析: 测量函数执行时间 (function_graph 跟踪器),分析中断或调度延迟,找出性能瓶颈 96。
- 理解代码流程: 跟踪特定函数的调用路径,了解内核在处理某个请求时的内部逻辑 99。
- 调试时序问题: 通过事件跟踪精确地记录事件发生的顺序和时间戳,帮助诊断与时序相关的 Bug 96。
- 与用户空间工具结合: ftrace 数据可以被用户空间的工具如 trace-cmd 98 或 Perfetto/Systrace (尤其在 Android 环境中 101) 读取和分析,生成更直观的可视化报告。
- 特定子系统调试: Ftrace 框架还包括一些专门的调试功能,如用于检测锁问题的 Lockdep 102,用于检测内存泄漏的 Kmemleak 102,以及用于检测内存错误的 KASan 102。
可观察性 vs. 交互性:
KGDB 和 Ftrace 代表了两种不同的内核调试哲学。
- KGDB 提供的是交互式调试 77。它允许你像调试用户程序一样暂停内核,检查任意内存和变量,并单步执行代码。这对于深入分析特定时刻的内核状态、理解复杂算法或定位导致崩溃的确切指令非常有用。但代价是必须中断内核的正常运行。
- Ftrace 提供的是可观察性 96。它在内核运行时记录信息,让你了解内核的动态行为、函数流程和时间特性,而不干扰其执行(尽管跟踪本身有开销)。这对于分析性能问题、理解实时交互或捕获间歇性事件非常有用,但它不允许你暂停内核或修改状态。
选择哪种工具取决于调试的目标:如果需要暂停执行并深入检查特定状态,选择 KGDB;如果需要观察运行中的内核行为、流程或性能,选择 Ftrace。两者有时也可以结合使用,例如使用 Ftrace 定位到可疑的代码区域,然后使用 KGDB 在该区域设置断点进行详细检查。
第 4 节:特定设备示例
本节将针对两种常见的嵌入式开发板——树莓派 (Raspberry Pi) 和 BeagleBone Black——提供具体的连接和调试设置示例,以阐明前述概念的实际应用。
4.1. 树莓派 (Raspberry Pi)
树莓派因其易用性和广泛的社区支持而备受欢迎。它提供了多种调试接口。
串行控制台 (UART):
这是访问树莓派(尤其是无头设置或启动失败时)最基本和可靠的方法之一。
- 硬件连接:
- 树莓派的 GPIO 排针上暴露了 UART 接口。通常使用 GPIO 14 (Pin 8) 作为 TXD (发送),GPIO 15 (Pin 10) 作为 RXD (接收),以及一个 GND 引脚 (如 Pin 6) 37。
- 需要一个 USB 转 TTL 串口适配器(确保电压匹配,树莓派 GPIO 通常是 3.3V)。将适配器的 GND 连接到 Pi 的 GND,适配器的 RXD 连接到 Pi 的 TXD (GPIO 14),适配器的 TXD 连接到 Pi 的 RXD (GPIO 15) 37。不要连接 VCC (电源) 引脚。
- 将 USB 转 TTL 适配器的 USB 端插入主机。
- 启用 UART:
- 默认情况下,树莓派的硬件 UART 可能被用于蓝牙或被禁用。需要在 /boot/config.txt 文件中启用它。将树莓派的 SD 卡插入另一台电脑,编辑 config.txt 文件(位于第一个 FAT32 分区,可在 Windows/macOS/Linux 上访问),在文件末尾添加一行:
enable_uart=1
38。有些文档也提到 enable_serial=1 103。 - 确保 /boot/cmdline.txt 文件中的 console= 参数指向正确的串行设备(通常是 serial0 或 ttyAMA0,取决于 Pi 型号和配置)并设置了波特率,例如 console=serial0,115200 103。有时默认配置已包含此项。
- 默认情况下,树莓派的硬件 UART 可能被用于蓝牙或被禁用。需要在 /boot/config.txt 文件中启用它。将树莓派的 SD 卡插入另一台电脑,编辑 config.txt 文件(位于第一个 FAT32 分区,可在 Windows/macOS/Linux 上访问),在文件末尾添加一行:
- 连接:
- 在主机上,使用终端仿真器(如 PuTTY, minicom, screen, CoolTerm 38)连接到 USB 转 TTL 适配器对应的串行端口 (COMx 或 /dev/ttyUSBx)。
- 设置波特率为 115200,数据位 8,无校验,停止位 1,无流控制 37。
- 给树莓派上电。您应该能在终端仿真器中看到启动信息和登录提示符。
USB Gadget 模式 (串行或以太网):
树莓派(特别是带有 USB OTG 功能的型号,如 Pi Zero, Zero W, Zero 2 W, 4B, A/A+ 系列)可以配置为 USB Gadget 设备,通过其 USB OTG 端口(Zero 上的 Micro USB,4B 上的 USB-C)模拟串行设备或网络适配器。
- 硬件连接: 使用合适的 USB 线缆将树莓派的 USB OTG 端口连接到主机 29。对于 Pi Zero,通常是 Micro USB 转 USB A 线缆。
- 启用 Gadget 模式:
- 编辑 SD 卡上的 /boot/config.txt,在末尾添加 dtoverlay=dwc2 29。
- 编辑 SD 卡上的 /boot/cmdline.txt,在 rootwait 参数之后(确保在同一行,用空格分隔)添加 modules-load=dwc2,g_ether (用于模拟以太网) 或 modules-load=dwc2,g_serial (用于模拟串行设备) 29。
- 以太网 Gadget (g_ether):
- IP 配置: 这是最棘手的部分。
- 静态 IP (推荐): 在树莓派上编辑 /etc/dhcpcd.conf (Raspberry Pi OS 使用 dhcpcd 管理网络),为 usb0 接口配置静态 IP,例如:
interface usb0
static ip_address=192.168.7.2/24
# 可选,如果需要通过主机路由: static routers=192.168.7.1
# 可选: static domain_name_servers=192.168.7.1
29。然后在主机上为对应的 USB 网络接口配置一个同一子网的静态 IP,例如 192.168.7.1 29。 - Zeroconf/Avahi: 理论上,如果两端都运行 Avahi/Bonjour 服务,可以通过 raspberrypi.local 访问树莓派,而无需手动配置 IP 29。但这在实践中可能不稳定 29,并且可能需要额外的配置或故障排除 30。
- 静态 IP (推荐): 在树莓派上编辑 /etc/dhcpcd.conf (Raspberry Pi OS 使用 dhcpcd 管理网络),为 usb0 接口配置静态 IP,例如:
- 连接: 配置好 IP 后,可以通过 ssh pi@192.168.7.2 (或 .local 名称) 连接 29。
- IP 配置: 这是最棘手的部分。
- 串行 Gadget (g_serial):
- 这种模式更简单,因为它避免了 IP 配置的复杂性 38。
- 启用后,树莓派会作为串行设备出现在主机上(例如 Linux 上的 /dev/ttyGS0 103 或 Windows 上的一个 COM 端口)。
- 然后可以使用终端仿真器像连接普通 USB 转串口适配器一样连接到这个虚拟串口。
4.2. BeagleBone Black (BBB)
BeagleBone Black 是一款流行的开源硬件平台,其设计考虑了易于通过 USB 进行连接和调试。
- USB 客户端连接 (默认模式):
- 硬件: 使用包装盒中附带的 Mini USB 转 USB A 线缆,将 BBB 上的 Mini USB 客户端端口(靠近 SD 卡槽)连接到主机的 USB 端口 53。BBB 可以通过此 USB 连接供电 53。
- 功能: 当 BBB 启动后(启动过程约 10-15 秒,USER LED 会闪烁 53),它会通过此 USB 连接向主机呈现两个功能:
- USB 大容量存储设备: 主机会看到一个名为 “BeagleBone Getting Started” 或类似的 U 盘。这个虚拟 U 盘包含了适用于 Windows 和 macOS 的网络驱动程序以及文档(如 start.htm,包含快速入门指南) 53。
- USB 网络适配器 (RNDIS/CDC Ethernet): BBB 会模拟一个网络适配器 53。
- 网络访问:
- 驱动: Windows 主机通常需要安装 U 盘中提供的 RNDIS 驱动程序才能识别网络适配器。Linux 和 macOS 通常内置了 CDC Ethernet 驱动,无需额外安装。
- IP 地址: BBB 上的 Linux 系统默认配置为在此 USB 网络接口上使用一个固定的 IP 地址。根据 Debian 镜像版本的不同,这个地址通常是 192.168.7.2 或 192.168.6.2 54。主机需要配置其对应的 USB 网络接口(安装驱动后出现)使用同一子网的 IP 地址(例如 192.168.7.1 或 192.168.6.1)。
- 访问: 配置好网络后,可以通过 SSH 连接到 BBB (ssh debian@192.168.7.2,默认用户名通常是 debian,密码可能是 temppwd 或空),或者通过 Web 浏览器访问 BBB 上运行的 Web 服务,例如 Cloud9 IDE 或 VS Code (通常在 http://192.168.7.2:3000 或 http://192.168.6.2:3000) 54。
- 串行调试头 (Serial Debug Header):
- BBB 板上有一个专用的 6 针 J1 接口(通常靠近 DC 电源插孔),提供了对处理器 UART0 的直接访问 39。
- 硬件: 需要一个 3.3V TTL USB 转串口适配器和合适的连接线(通常是杜邦线或专门的连接器,如 JST ZH 39)。连接 GND, TXD (BBB Pin 4), RXD (BBB Pin 5) 39。注意不要连接 VCC。
- 用途: 这个接口独立于 USB 客户端端口,主要用于访问引导加载程序 (U-Boot) 的控制台和查看非常早期的内核启动消息,或者在 USB 客户端功能完全失效时进行调试。
- 连接: 使用终端仿真器(PuTTY, minicom, screen)连接到适配器对应的 COM 端口或 /dev/ttyUSBx,波特率通常为 115200,8N1 39。
- 电源注意事项:
- 虽然 BBB 可以通过 USB 客户端端口供电,但如果连接了耗电的外设(通过 USB Host 端口或 Cape 扩展板),或者进行 eMMC 刷写等高功耗操作时,USB 供电可能不足 53。
- 在这种情况下,需要使用外部 5V DC 电源适配器(圆口插头)供电 53。刷写板载 eMMC 存储器时,必须使用外部 5V 电源 54。
- 可以通过按下电源按钮来正常关机 53。
这些设备特定的示例展示了如何应用前面讨论的通用连接方法,并强调了查阅设备文档以获取准确引脚、配置步骤和默认设置的重要性。
第 5 节:常见问题排查与建议
在通过数据线调试 Linux 设备的过程中,可能会遇到各种连接或配置问题。本节旨在提供一些常见问题的排查思路和选择调试方法的建议。
5.1. 连接问题
串行连接问题:
- 终端无任何输出:
- 检查物理连接: 确认 TX 和 RX 线是否正确交叉连接 (TX -> RX, RX -> TX),GND 是否连接 38。
- 检查电源: 确认目标 Linux 设备已上电。
- 检查端口选择: 确认主机上的终端仿真器选择了正确的 COM 端口 (Windows) 或 /dev/tty* 设备文件 (Linux) 5。
- 检查波特率: 确认终端仿真器设置的波特率、数据位、校验位、停止位与目标设备完全一致 5。
- 检查设备端 UART 配置: 确认目标设备的 UART 接口已在硬件层面启用,并且内核或引导加载程序配置为使用该 UART 作为控制台 38。
- 检查驱动: 确认主机已正确安装 USB 转 TTL 适配器的驱动程序 3。
- 终端输出乱码:
- 最常见的原因是波特率不匹配 5。仔细核对并确保两端设置一致。
- 数据位、校验位或停止位设置错误也可能导致乱码。通常应为 8N1 (8 数据位, 无校验, 1 停止位) 5。
- 权限被拒绝 (Linux):
- 无法打开 /dev/ttyUSBx 或 /dev/ttySx 设备。尝试使用 sudo 运行终端仿真器 5。
- 或者,将当前用户添加到 dialout 组 (sudo usermod -aG dialout $USER),然后注销并重新登录 36。
USB 网络 / SSH 连接问题:
- 设备未被识别为网络适配器:
- 检查驱动 (Windows): 确保已安装适用于设备的 RNDIS 或 CDC Ethernet 驱动 23。检查设备管理器中是否有未知设备或网络适配器错误 4。
- 检查设备端配置 (Linux Gadget): 确认内核已加载 g_ether 或相关 USB 网络模块 23。使用 dmesg 检查是否有相关错误消息。
- IP 地址问题:
- 设备或主机没有获取到 IP 地址。
- 设备和主机的 IP 地址不在同一个子网内 11。
- IP 地址冲突(两端配置了相同的 IP)。
- 使用 ip addr (Linux) 或 ipconfig (Windows) 检查两端的接口状态和 IP 配置 11。
- ping 失败:
- 确认目标 IP 地址正确无误。
- 检查两端的网络接口是否都已启用 (UP 状态) 25。
- 检查两端的防火墙设置是否阻止了 ICMP 请求或响应 50。
- 检查路由设置(虽然在简单的点对点 USB 网络中通常不是问题)。
- SSH 连接被拒绝 (Connection Refused):
- 目标设备上的 sshd 服务未运行或未启用 60。使用 systemctl status sshd 或 service sshd status 检查。
- 目标设备上的防火墙阻止了 SSH 端口 (默认为 22) 的入站连接 50。
- SSH 认证失败 (Permission Denied):
- 输入的用户名或密码错误。
- 如果使用 SSH 密钥认证,检查密钥文件权限、~/.ssh/authorized_keys 文件内容是否正确。
- SSH 连接超时 (Timeout):
- 网络连接不稳定或中断。
- 路由问题(不常见于 USB 直连)。
- 防火墙可能在连接建立过程中阻止了通信。
- Zeroconf (.local 名称) 解析失败:
- 主机或设备未运行 Avahi/Bonjour 服务 29。
- 网络防火墙阻止了 mDNS (UDP 端口 5353) 通信。
- 设备可能尚未广播其 .local 名称。尝试使用 avahi-browse -art 等工具发现 30。
5.2. 选择正确的调试方法
面对一个需要调试的 Linux 设备,选择合适的连接方法和工具是高效解决问题的关键。
- 选择连接方法:
- 串行控制台:
- 优点: 最底层、最可靠的访问方式;通常在引导加载程序阶段和内核启动早期即可用;不受网络配置或服务状态影响。
- 缺点: 功能有限(主要是文本交互);速度较慢;需要特定的硬件适配器和物理访问。
- 适用场景: 设备无法启动、内核崩溃 (Panic)、网络服务失效、需要访问引导加载程序 (U-Boot 等)、进行非常底层的硬件或驱动调试。
- USB 网络 (SSH):
- 优点: 提供完整的远程 Shell 环境;支持文件传输 (SCP/SFTP);可以使用更丰富的网络工具;速度通常比串口快。
- 缺点: 配置相对复杂(IP 地址、子网、驱动、SSH 服务);依赖于设备内核和网络服务的正常运行;无法访问引导加载程序或非常早期的启动信息。
- 适用场景: 调试应用程序、配置系统服务、传输调试脚本或日志文件、需要稳定且功能丰富的远程访问。
- 串行控制台:
- 选择调试工具 (由简到繁):
- 基础检查 (ping, top/htop, 日志): 在遇到问题时,首先进行基础检查。使用 ping 确认网络连通性 57。使用 top 或 htop 查看是否有异常的进程占用过多资源 64。检查系统日志 (dmesg, journalctl, /var/log) 查找错误或警告信息 16。
- 系统调用跟踪 (strace): 当怀疑问题与程序和系统的交互有关(如文件访问、网络调用失败)时,使用 strace 75。它可以精确定位到失败的系统调用及其错误原因。
- 应用程序调试 (gdb): 当需要深入分析应用程序的内部逻辑、查找段错误或检查变量状态时,使用 gdb 89。前提是程序使用 -g 编译。
- 内核跟踪/调试 (ftrace/kgdb): 当问题明确指向内核、驱动程序或性能瓶颈时,才考虑使用 ftrace 进行非侵入式跟踪 96,或使用 kgdb 进行侵入式的交互式内核调试 77。这些工具需要更专业的知识和更复杂的设置。
遵循从简单到复杂、从用户空间到内核空间的排查思路,通常能更有效地定位和解决问题。
5.3. 进一步的资源
为了更深入地了解本报告中涉及的工具和技术,建议参考以下资源:
- 工具官方文档:
- GDB: https://www.gnu.org/software/gdb/documentation/
- strace: man strace 或在线手册页
- iproute2 (包含 ip 和 ss): man ip, man ss
- systemd (包含 journalctl): man journalctl, man systemd.journal-fields
- Linux 内核文档 (包含 KGDB, Ftrace): https://www.kernel.org/doc/html/latest/ (93)
- 设备特定文档:
- 树莓派文档: https://www.raspberrypi.com/documentation/ (104)
- BeagleBoard 文档 (包含 BeagleBone Black): https://docs.beagleboard.org/ (41)
- 在线教程与文章: 本报告引用的来源(如 Baeldung, GeeksforGeeks, Red Hat Blog, Stack Overflow 等)提供了许多关于特定命令和技术的详细教程和示例。
结论
通过数据线调试连接到计算机的 Linux 设备是一个涉及硬件连接、主机和设备配置以及运用各种诊断工具的系统性过程。本报告详细阐述了两种主要的连接途径——串行控制台和 USB 网络——各自的设置方法、优缺点和适用场景。
成功的调试始于正确识别设备在主机上的呈现方式(COM 端口、网络适配器或 tty 设备),并强调了理解动态命名与持久化命名机制对于建立稳定连接的重要性。随后,报告深入介绍了建立串行连接所需的硬件、软件(PuTTY, minicom, screen)和必须精确匹配的通信参数。对于功能更强大的 USB 网络连接,报告涵盖了设备端 Gadget 模式的配置、主机端的网络设置、IP 地址分配策略(静态、DHCP、Zeroconf)以及建立 SSH 连接的步骤,并指出了其相对于串行连接的复杂性。
在建立连接之后,掌握基础的 Linux 调试技术至关重要。报告系统地介绍了用于监控进程和性能的 ps, top, htop;用于分析系统日志和内核消息的 dmesg, journalctl 和 /var/log 文件查看工具;用于跟踪应用程序系统调用的 strace;以及用于源代码级应用程序调试的 gdb。报告还强调了关联不同日志来源以及利用 strace 揭示隐藏系统交互的重要性。此外,简要概述了用于更深层次内核调试的 KGDB 和 Ftrace 工具,并对比了它们在交互性与可观察性上的差异。
最后,报告通过树莓派和 BeagleBone Black 的具体示例,将理论知识应用于实践,并提供了常见连接问题的排查指南和选择调试方法的建议。
总之,有效地通过数据线调试 Linux 设备需要结合对连接方式的理解、对设备识别和配置的细致操作,以及对 Linux 提供的丰富调试工具集的熟练运用。采取系统化的方法,从基础检查入手,逐步深入,并善用文档资源,是成功诊断和解决问题的关键。
Works cited
- Universal Serial Bus Viewer in Windows - Windows drivers | Microsoft Learn, accessed April 22, 2025, https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/usbview
- Check Your COM Port on Windows 10, accessed April 22, 2025, https://www.virtual-serial-port.org/articles/com-port-on-windows-10/
- Identify your device’s COM Port with Device Manager – TAL …, accessed April 22, 2025, https://www.taltech.com/support/identify-com-port/
- How to Fix When Windows Cannot Detect USB Device - StarTech.com, accessed April 22, 2025, https://www.startech.com/en-us/faq/windows-cannot-detect-usb-device
- PuTTY Setup • ECEn 220: Fundamentals of Digital Systems, accessed April 22, 2025, https://ecen220wiki.groups.et.byu.net/tutorials/other/01_putty_setup/
- A Comprehensive Guide to Choose the Right USB to Serial Cable - VCOM International Ltd, accessed April 22, 2025, https://www.vcom.com.hk/shows/169/445.html
- How to identify Com Ports in Windows10 - Microsoft Community, accessed April 22, 2025, https://answers.microsoft.com/en-us/windows/forum/all/how-to-identify-com-ports-in-windows10/2591ed8b-805e-4e66-9513-836cdd49ed80
- How to find the network device name and download the driver - Windows - Lenovo Support, accessed April 22, 2025, https://support.lenovo.com/gt/en/solutions/ht078107-how-to-find-and-download-network-driver-windows
- How do I find my Ethernet cable in device manager - Microsoft Community, accessed April 22, 2025, https://answers.microsoft.com/en-us/windows/forum/all/how-do-i-find-my-ethernet-cable-in-device-manager/50d099f2-1706-407e-a01c-58cc178f10fe
- ipconfig - Get all the connected USB device’s IP address - Super User, accessed April 22, 2025, https://superuser.com/questions/453536/ipconfig-get-all-the-connected-usb-devices-ip-address
- Tips on How to Find the IP Address Assigned to Your Ethernet …, accessed April 22, 2025, https://docs.ceruleansonar.com/c/tracker-650/communicating-with-the-tracker-650/tips-on-how-to-find-the-ip-address-assigned-to-your-ethernet-adapter
- How to Check Whether a USB Device Is Present on a Linux Machine …, accessed April 22, 2025, https://www.baeldung.com/linux/check-for-usb-devices
- Introduction to Basic Troubleshooting Terminal Commands in Ubuntu Linux | Dell Thailand, accessed April 22, 2025, https://www.dell.com/support/kbdoc/en-th/000123974/introduction-to-basic-troubleshooting-commands-within-ubuntu-linux
- www.serial-over-ethernet.com, accessed April 22, 2025, https://www.serial-over-ethernet.com/linux-serial-port/#:~:text=to%20Ethernet%20Connector-,Checking%20Your%20Ports,the%20output%20of%20this%20command.&text=The%20devices%20will%20be%20listed%20along%20with%20their%20corresponding%20device%20file%20names.
- Linux Serial Port Guide - Serial over Ethernet, accessed April 22, 2025, https://www.serial-over-ethernet.com/linux-serial-port/
- Linux dmesg Command: Syntax, Options, Examples - phoenixNAP, accessed April 22, 2025, https://phoenixnap.com/kb/dmesg-linux
- Linux Dmesg command explained - Cloudfanatic, accessed April 22, 2025, https://my.cloudfanatic.net/index.php/knowledgebase/87/Linux-Dmesg-command-explained.html?language=french
- Dmesg and Linux kernel log - stm32mpu - ST wiki, accessed April 22, 2025, https://wiki.st.com/stm32mpu/wiki/Dmesg_and_Linux_kernel_log
- How to View Kernel Messages in Linux | dmesg Command - GeeksforGeeks, accessed April 22, 2025, https://www.geeksforgeeks.org/how-to-use-the-dmesg-command-on-linux/
- How to find all serial devices (ttyS, ttyUSB, …) on Linux without opening them?, accessed April 22, 2025, https://stackoverflow.com/questions/2530096/how-to-find-all-serial-devices-ttys-ttyusb-on-linux-without-opening-them
- How to find my serial port number - MarineTraffic, accessed April 22, 2025, https://support.marinetraffic.com/en/articles/9552959-how-to-find-my-serial-port-number
- How to List Serial Ports on Linux - Dracula Servers Tutorials, accessed April 22, 2025, https://draculaservers.com/tutorials/list-serial-ports-on-linux/
- How to Use USB Gadget Ethernet | Timesys LinuxLink, accessed April 22, 2025, https://linuxlink.timesys.com/docs/wiki/engineering/HOWTO_Use_USB_Gadget_Ethernet
- How can I find the USB wireless adapter into the dmesg log file? - Super User, accessed April 22, 2025, https://superuser.com/questions/760449/how-can-i-find-the-usb-wireless-adapter-into-the-dmesg-log-file
- Linux networking: ifconfig versus ip - Red Hat, accessed April 22, 2025, https://www.redhat.com/en/blog/ifconfig-vs-ip
- Linux Basics: Network Configuration and Troubleshooting using ifconfig ip - PureVoltage, accessed April 22, 2025, https://purevoltage.com/2023/10/05/linux-basics-network-configuration-and-troubleshooting-using-ifconfig-ip-netstat/
- 7 Examples of ip addr Command in Linux - Greenwebpage Community, accessed April 22, 2025, https://greenwebpage.com/community/7-examples-of-ip-addr-command-in-linux/
- ifconfig Command | GeeksforGeeks, accessed April 22, 2025, https://www.geeksforgeeks.org/ifconfig-command-in-linux-with-examples/
- Raspberry Pi Console over USB: Configuring an Ethernet Gadget (Shallow Thoughts), accessed April 22, 2025, https://shallowsky.com/blog/linux/raspberry-pi-ethernet-gadget.html
- [Solved] Connecting to Raspberry Pi Zero using USB ethernet and Avahi / Networking, Server, and Protection / Arch Linux Forums, accessed April 22, 2025, https://bbs.archlinux.org/viewtopic.php?id=213926
- get the IP address of USB device in Linux - Super User, accessed April 22, 2025, https://superuser.com/questions/894684/get-the-ip-address-of-usb-device-in-linux
- STICKY: USB Ethernet Gadget A Beginner’s Guide - Page 2 - Raspberry Pi Forums, accessed April 22, 2025, https://forums.raspberrypi.com/viewtopic.php?t=306121&start=25
- How to config USB ethernet to have a static IP? - Ask Ubuntu, accessed April 22, 2025, https://askubuntu.com/questions/717671/how-to-config-usb-ethernet-to-have-a-static-ip
- Need Help Improving Zero USB Ethernet Gadget setup / HOWTO - Raspberry Pi Forums, accessed April 22, 2025, https://forums.raspberrypi.com/viewtopic.php?t=168285
- Serial debugging/Cable schematics - postmarketOS Wiki, accessed April 22, 2025, https://wiki.postmarketos.org/wiki/Serial_debugging/Cable_schematics
- Unlocking Serial Connectivity on Linux: A Comprehensive Guide - DEV Community, accessed April 22, 2025, https://dev.to/s3cloudhub/unlocking-serial-connectivity-on-linux-a-comprehensive-guide-25n3
- Raspberry Pi - Serial Console : 4 Steps (with Pictures) - Instructables, accessed April 22, 2025, https://www.instructables.com/Raspberry-Pi-Serial-Console/
- Attaching to a Raspberry Pi’s Serial Console (UART) for debugging | Jeff Geerling, accessed April 22, 2025, https://www.jeffgeerling.com/blog/2021/attaching-raspberry-pis-serial-console-uart-debugging
- BeagleBone AI (BB-AI) - Getting Started - element14 Community, accessed April 22, 2025, https://community.element14.com/products/devtools/single-board-computers/next-genbeaglebone/b/blog/posts/beaglebone-ai-bb-ai—getting-started
- Serial Terminal - Headless Raspberry Pi Setup - SparkFun Learn, accessed April 22, 2025, https://learn.sparkfun.com/tutorials/headless-raspberry-pi-setup/serial-terminal
- Connectors - BeagleBoard Documentation, accessed April 22, 2025, https://docs.beagleboard.org/boards/beaglebone/black/ch07.html
- USB 3.0 Super-Speed A/A Debugging Cable - DataPro International, accessed April 22, 2025, https://www.datapro.net/products/usb-3-0-super-speed-a-a-debugging-cable.html
- How to Connect to USB Console by Using PuTTY? - Instructables, accessed April 22, 2025, https://www.instructables.com/How-to-Connect-to-USB-Console-by-Using-PuTTY/
- PuTTY Tutorial for Serial COM (step-by-step guide) - YouTube, accessed April 22, 2025, https://www.youtube.com/watch?v=dO-BMOzNKcI
- Linux minicom Command with Practical Examples | LabEx, accessed April 22, 2025, https://labex.io/tutorials/linux-linux-minicom-command-with-practical-examples-422802
- Minicom Setup for Linux PCs, accessed April 22, 2025, https://microchip.my.site.com/s/article/Minicom-Setup-for-Linux-PCs
- Serial Port Programming Part 1 - Setting Baud Rate - Embedded Guru, accessed April 22, 2025, http://embeddedguruji.blogspot.com/2019/01/serial-port-programming-part-1-setting.html
- Configuring Serial Port on Linux - Baeldung, accessed April 22, 2025, https://www.baeldung.com/linux/serial-port-configuration
- Connecting to a Linux device with SSH - UMH Learning Center, accessed April 22, 2025, https://learn.umh.app/course/connecting-with-ssh/
- How to Connect to a Remote Server via SSH from Windows, Linux …, accessed April 22, 2025, https://phoenixnap.com/kb/ssh-to-connect-to-remote-server-linux-or-windows
- How to use SSH to connect to a remote server in Linux | ssh Command - GeeksforGeeks, accessed April 22, 2025, https://www.geeksforgeeks.org/ssh-command-in-linux-with-examples/
- How to set up autoip with local-link (RNDIS) on linux and embedded linux - Stack Overflow, accessed April 22, 2025, https://stackoverflow.com/questions/20149645/how-to-set-up-autoip-with-local-link-rndis-on-linux-and-embedded-linux
- Connecting Up Your BeagleBone Black - BeagleBoard Documentation, accessed April 22, 2025, https://docs.beagleboard.org/latest/boards/beaglebone/black/ch03.html
- Basics - BeagleBoard Documentation, accessed April 22, 2025, https://docs.beagleboard.org/books/beaglebone-cookbook/01basics/basics.html
- Routing zeroconf interfaces - Unix & Linux Stack Exchange, accessed April 22, 2025, https://unix.stackexchange.com/questions/549937/routing-zeroconf-interfaces
- Link-local (zeroconf) networking with multiple hosts/interfaces - Super User, accessed April 22, 2025, https://superuser.com/questions/904091/link-local-zeroconf-networking-with-multiple-hosts-interfaces
- Guide to Network Troubleshooting in Linux - LinuxBlog.io, accessed April 22, 2025, https://linuxblog.io/guide-to-network-troubleshooting-in-linux/
- Ping command basics for testing and troubleshooting - Red Hat, accessed April 22, 2025, https://www.redhat.com/en/blog/ping-usage-basics
- Linux ping Command with Examples | phoenixNAP KB, accessed April 22, 2025, https://phoenixnap.com/kb/linux-ping-command-examples
- How to Check If SSH Server Is Running on Linux? A Complete Guide - Bdwebit, accessed April 22, 2025, https://bdwebit.com/blog/how-to-check-if-ssh-server-is-running-on-linux/
- How to Enable SSH on Ubuntu 20.04 LTS - Linode, accessed April 22, 2025, https://www.linode.com/docs/guides/enable-ssh-ubuntu/
- How to check if SSH service is up and running in Servers - ManageEngine Pitstop, accessed April 22, 2025, https://pitstop.manageengine.com/portal/en/kb/articles/how-to-check-ssh-service-is-up-and-running-in-servers
- Identify Your Intel® Ethernet Controller from the Device Manager, accessed April 22, 2025, https://www.intel.com/content/www/us/en/support/articles/000024969/ethernet-products/legacy-ethernet-products.html
- How to Check Running Processes in Linux Using ps, top, htop, and atop Commands, accessed April 22, 2025, https://runcloud.io/blog/running-processes-in-linux
- What is the difference between ps and top command? - Unix & Linux Stack Exchange, accessed April 22, 2025, https://unix.stackexchange.com/questions/62176/what-is-the-difference-between-ps-and-top-command
- process monitors for Linux - comparing top and htop - YouTube, accessed April 22, 2025, https://www.youtube.com/watch?v=CAUc8aq4qtU
- Log Management with Journalctl: A SysAdmin’s Guide | Better Stack Community, accessed April 22, 2025, https://betterstack.com/community/guides/logging/how-to-control-journald-with-journalctl/
- Linux Logs: How to View, Read & Configure - phoenixNAP, accessed April 22, 2025, https://phoenixnap.com/kb/how-to-view-read-linux-log-files
- Understanding Linux Log File Locations: A Comprehensive Guide | Siberoloji, accessed April 22, 2025, https://www.siberoloji.com/understanding-linux-log-file-locations-a-comprehensive-guide/
- How To Use journalctl to View and Manipulate Systemd Logs - Rackspace Technology, accessed April 22, 2025, https://docs.rackspace.com/docs/how-to-use-journalctl-to-view-and-manipulate-systemd-logs
- journalctl Commands Cheatsheet for Troubleshooting - Last9, accessed April 22, 2025, https://last9.io/blog/journalctl-commands-cheatsheet/
- systemd’s journalctl: how to filter by message? - Server Fault, accessed April 22, 2025, https://serverfault.com/questions/754953/systemds-journalctl-how-to-filter-by-message
- Linux Logging Guide: The Basics - CrowdStrike, accessed April 22, 2025, https://www.crowdstrike.com/en-us/guides/linux-logging/
- How To View and Configure Linux Logs on Ubuntu, Debian, and CentOS | DigitalOcean, accessed April 22, 2025, https://www.digitalocean.com/community/tutorials/how-to-view-and-configure-linux-logs-on-ubuntu-debian-and-centos
- Linux strace Command with Practical Examples - LabEx, accessed April 22, 2025, https://labex.io/tutorials/linux-linux-strace-command-with-practical-examples-422933
- Strace command in Linux with Examples | GeeksforGeeks, accessed April 22, 2025, https://www.geeksforgeeks.org/strace-command-in-linux-with-examples/
- How is Linux kernel live debugging done and what tools are used? - Stack Overflow, accessed April 22, 2025, https://stackoverflow.com/questions/4943857/how-is-linux-kernel-live-debugging-done-and-what-tools-are-used
- How to better understand and reverse-engineer system calls within processes given a specific example, accessed April 22, 2025, https://unix.stackexchange.com/questions/788796/how-to-better-understand-and-reverse-engineer-system-calls-within-processes-give
- Attaching strace to 100% CPU Apache process - output - Server Fault, accessed April 22, 2025, https://serverfault.com/questions/330844/attaching-strace-to-100-cpu-apache-process-output
- How does strace connect to an already running process? - Stack Overflow, accessed April 22, 2025, https://stackoverflow.com/questions/7482076/how-does-strace-connect-to-an-already-running-process
- How to strace all write calls (to stdout/stderr) from all child processes inside a docker container? - Unix & Linux Stack Exchange, accessed April 22, 2025, https://unix.stackexchange.com/questions/419997/how-to-strace-all-write-calls-to-stdout-stderr-from-all-child-processes-inside
- Track Child Processes Using strace | Baeldung on Linux, accessed April 22, 2025, https://www.baeldung.com/linux/strace-track-child-processes
- Using Strace to Trace Linux Syscalls - YouTube, accessed April 22, 2025, https://www.youtube.com/watch?v=mBfurelWwPQ&pp=0gcJCdgAo7VqN5tD
- Pass and access request response object in child process using fork - Stack Overflow, accessed April 22, 2025, https://stackoverflow.com/questions/35716675/pass-and-access-request-response-object-in-child-process-using-fork
- Debugging hanging child process with strace - LinuxQuestions.org, accessed April 22, 2025, https://www.linuxquestions.org/questions/linux-software-2/debugging-hanging-child-process-with-strace-884752/
- Processes, forks and executions - part 2 - CFEngine, accessed April 22, 2025, https://cfengine.com/blog/2022/processes-part-2/
- Lab 4: Tracing System Calls, accessed April 22, 2025, https://www.cs.usfca.edu/~mmalensek/cs326/assignments/lab4.html
- Running strace in the background - linux - Stack Overflow, accessed April 22, 2025, https://stackoverflow.com/questions/51244646/running-strace-in-the-background
- GDB Tutorial, accessed April 22, 2025, https://web.eecs.umich.edu/~sugih/pointers/summary.html
- GDB (Step by Step Introduction) - GeeksforGeeks, accessed April 22, 2025, https://www.geeksforgeeks.org/gdb-step-by-step-introduction/
- Tutorial of gcc and gdb, accessed April 22, 2025, https://cseweb.ucsd.edu/classes/fa09/cse141/tutorial_gcc_gdb.html
- How to debug C++ Programs using GDB (GNU Debugger) in Linux - YouTube, accessed April 22, 2025, https://m.youtube.com/watch?v=jc_uzRWSrvw&pp=ygUMI2dkYmNvbXBpbGVy
- Using kgdb, kdb and the kernel debugger internals, accessed April 22, 2025, https://www.kernel.org/doc/html/v4.14/dev-tools/kgdb.html
- How to use KGDB | Timesys LinuxLink, accessed April 22, 2025, https://linuxlink.timesys.com/docs/how_to_use_kgdb
- Chapter 10. Kernel Debugging | FreeBSD Documentation Portal, accessed April 22, 2025, https://docs.freebsd.org/en/books/developers-handbook/kerneldebug/
- ftrace - Function Tracer — The Linux Kernel documentation, accessed April 22, 2025, https://www.kernel.org/doc/html/v5.0/trace/ftrace.html
- Ftrace - stm32mpu - ST wiki, accessed April 22, 2025, https://wiki.st.com/stm32mpu/wiki/Ftrace
- Appendix B. Detailed Description of Ftrace | Red Hat Product Documentation, accessed April 22, 2025, https://docs.redhat.com/en/documentation/red_hat_enterprise_linux_for_real_time/7/html/tuning_guide/appe-detailed_description_of_ftrace
- Introduction to kernel tracing with ftrace - devkernel.io, accessed April 22, 2025, https://devkernel.io/posts/ftrace_intro/
- Linux Tracing Technologies - The Linux Kernel documentation, accessed April 22, 2025, https://docs.kernel.org/trace/index.html
- Use ftrace | Android Open Source Project, accessed April 22, 2025, https://source.android.com/docs/core/tests/debug/ftrace
- Debugging — The Linux Kernel documentation, accessed April 22, 2025, https://linux-kernel-labs.github.io/refs/heads/master/lectures/debugging.html
- Setting up serial console on a new image - Raspberry Pi Forums, accessed April 22, 2025, https://forums.raspberrypi.com/viewtopic.php?t=339660
- Raspberry Pi - Void Linux Handbook, accessed April 22, 2025, https://docs.voidlinux.org/installation/guides/arm-devices/raspberry-pi.html
- 6.2.8. Flashing eMMC on BeagleBone Black via SD Card - Texas Instruments, accessed April 22, 2025, https://software-dl.ti.com/processor-sdk-linux/esd/docs/latest/linux/How_to_Guides/Target/How_to_Program_Beaglebone_Black_eMMC_via_SD_Card.html
- BeagleBone Black - BeagleBoard Documentation, accessed April 22, 2025, https://docs.beagleboard.org/latest/boards/beaglebone/black/