# 配置调试方法

使用以下方法了解内核调试方式的基本分类，并报告 Qualcomm Linux 内核中固有的调试功能识别出的问题。

有关调试的更多信息，请参见 [Qualcomm Linux 调试指南](bundle/publicresource/topics/80-70022-12)。

## 使用 printk 进行调试

使用 `printk` 技术在 Linux 内核中进行调试，以打印信息并进行跟踪。

在 `include/linux/printk.h` 中定义的 printk 包装器支持为日志语句添加日志级别。例如：

pr_emerg("At line %d: Func: %s\n", __LINE__, __func__);
    pr_info("At line");
    Copy to clipboard

有关详细信息，参见 [Message logging with printk](https://www.kernel.org/doc/html/next/core-api/printk-basics.html)。

## 编译设备树

要调试设备树，请执行以下操作：

1. 使用 `devtool modify linux-qcom-custom` 命令克隆内核代码。
2. 在设备树中进行更改。
3. 使用 `bitbake dtb-qcom-image` 命令编译 DTB。
4. 使用 `fastboot` 命令将 `build-qcom-wayland/tmp-glibc/deploy/images/qcs6490-rb3gen2-vision-kit/dtb-qcom-image-qcs6490-rb3gen2-vision-kit.rootfs.vfat`（与 dtb.bin 相同）刷写到 `dtb_a` 和 `dtb_b` 分区。
5. 重新启动设备。

## 调试内核模块

要调试内核模块，请执行以下操作：

1. 使用 `devtool modify linux-qcom-custom` 命令克隆内核代码。
2. 默认情况下，内核模块签名是禁用的。要手动禁用内核模块签名配置 `CONFIG_MODULE_SIG`，请使用 `menuconfig` 命令。有关 `menuconfig` 命令的更多信息，请参阅[配置内核](https://docs.qualcomm.com/doc/80-70022-3SC/topic/kernel-development.html#kernel-configuration3)。

CONFIG_MODULE_SIG
        Copy to clipboard

CONFIG_MODULE_SIG_FORCE
        Copy to clipboard

Note

这是一次性步骤。
3. 更改内核或模块。
4. 使用 `bitbake esp-qcom-image` 命令重新编译内核模块。
5. 将 `tmp-glibc/deploy/images/qcs6490-rb3gen2-vision-kit/linux-qcs6490-rb3gen2-vision-kit.efi` 内核镜像推送到设备的 `/tmp` 目录下，并将其重命名为 `vmlinuz`（内核二进制文件）。
6. 使用 `cp /tmp/vmlinuz /boot/ostree/poky-<SHA>/vmlinuz-6.6.52-03343-gdfbbed24a2c5-dirty` 命令更新内核。
7. 将 `build-qcom-wayland/tmp-glibc/deploy/images/qcs6490-rb3gen2-vision-kit/modules--6.6-r0-qcs6490-rb3gen2-vision-kit-<DATE>.tgz` 内核模块推送到设备的 `/tmp` 目录下。
8. 使用 `mount -o remount,rw /` 和 `mount -o remount,rw /usr` 命令重新挂载 root。
9. 使用 `tar -xzf modules--6.6-r0-qcs6490-rb3gen2-vision-kit-<DATE>.tgz` 命令解压。
10. 使用 `cp -rf /tmp/lib/modules/6.6.65-debug-04076-g029659012248-dirty/ /lib/modules/` 命令更新内核模块。
11. 重新启动设备。

要永久禁用模块签名，请执行以下步骤：

1. 禁用以下内核配置选项：

CONFIG_MODULE_SIG
        CONFIG_MODULE_SIG_FORCE
        Copy to clipboard
2. 在 `conf/machine/include/qcom-base.inc` 文件中，删除以下行：

INHERIT += " qmodule"
        Copy to clipboard
3. 在 `recipes-kernel/linux/linux-qcom-custom_6.6.bb` 文件中，删除以下行：

do_package[nostamp] = "1"
        Copy to clipboard

## 使用日志级别进行调试

可以使用 `/linux/printk.h` 中定义的任何其他日志级别打印消息控制台日志通过 printk 中使用的日志级别和设备上选择的日志级别进行控制。

根据用例选择日志级别。如果在频繁调用的函数中选择较低的日志级别，可能会生成大量日志。

以下示例所示为内核打印级别的日志：

pr_info("At func %s\n", __func__);
    pr_notice("At func %s\n", __func__);
    pr_warn("At func %s\n", __func__);
    pr_err("At func %s\n", __func__);
    pr_crit("At func %s\n", __func__);
    pr_alert("At func %s\n", __func__);
    pr_emerg("At func %s\n", __func__);
    Copy to clipboard

## 启用并挂载 debugfs 文件系统

Debugfs 是一种文件系统，可帮助内核开发人员向用户空间提供内核信息。

Debugfs 用于访问内核数据结构和变量、跟踪事件、调试消息和统计信息。

- 确保你的内核配置有 `CONFIG_DEBUG_FS` 设置（默认启用）。
- 如果尚未启用，可以使用 `menuconfig` 在内核配置中启用。
- 如果 debugfs 未默认挂载，请挂载。

mount -t debugfs none /sys/kernel/debug
        Copy to clipboard

## 使用内核探针进行调试

Kprobes 用于在不影响系统运行的情况下探入任何内核例程，收集调试和性能信息。

内核代码地址使用触发断点时调用的处理程序例程采集。在调度器调试期间，Kprobes 很有用，您可以在不同的调度事件中生成追踪信息以了解系统行为。

有关详细信息，参见 [Kernel Probes](https://www.kernel.org/doc/html/next/trace/kprobes.html)。

## 配置 Ftrace 进行分析和跟踪

ftrace 提供了跟踪工具，可实现全系统分析和 runtime 跟踪。

有关 ftrace 的更多信息，请参见[函数跟踪](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-12/debugging_linux_kernel.html#function-tracer)。

### 启用 memory-mapped 的输入/输出跟踪

Qualcomm Linux 内核中的内存映射 I/O (MMIO) 跟踪功能可提供相关信息，便于用户了解驱动程序如何与 MMIO 设备及其相关硬件状态进行交互。

通用 MMIO 跟踪使用 `__raw_{read,write}{b,l,w,q}` 访问器用于对内存映射寄存器执行读/写操作。

在下列情况下，设备会挂起，或者一些未定义的行为会导致设备崩溃：

> 
> 
> 表：设备崩溃的原因
> 
> 
> | 原因 | 说明 |
> | --- | --- |
> | 无时钟时的访问 | 如果对寄存器空间的访问没有时钟信号控制，则设备会崩溃。 |
> | 受保护的寄存器空间 | 如果寄存器空间受到保护，并且未设置为允许非安全世界访问，则会发生异常。例如，仅允许异常级别 (EL3) 的访问，禁止任何 EL2/EL1 访问。 |
> | xPU 控制 | xPU 内存保护单元控制特定客户端对特定内存或寄存器区域的访问。 |

上述情况会导致立即重启、同步错误 (SErrors)/片上网络 (NoC) 问题或互连挂起。`CONFIG_TRACE_MMIO_ACCESS` 提供 ftrace 跟踪事件来记录此类 MMIO 寄存器访问，具备提前启用跟踪事件、过滤功能以及将 ftrace 日志 dump 到控制台的能力。

以下所示为启用 MMIO 跟踪后跟踪缓冲区的输出示例：

# List all rwmmio trace events
      cat /sys/kernel/tracing/available_events | grep rwmmio
    
    # Enable all rwmmio trace events
      cat /sys/kernel/tracing/available_events | grep rwmmio >> /sys/kernel/tracing/set_event
    
    # List all traces
      cat /sys/kernel/tracing/trace
    rwmmio_read: gic_peek_irq+0xd0/0xd8 readl addr=0xffff800010040104
    rwmmio_write: gic_poke_irq+0xe4/0xf0 writel addr=0xffff800010040184
    rwmmio_read: gic_do_wait_for_rwp+0x54/0x90 readl addr=0xffff800010040000
    rwmmio_write: gic_set_affinity+0x1bc/0x1e8 writeq addr=0xffff800010046130
    Copy to clipboard

Last Published: Nov 04, 2025

[Previous Topic
采集内核日志](https://docs.qualcomm.com/bundle/publicresource/80-70022-3SC/topics/capture-the-kernel-logs.md) [Next Topic
从设备访问内容](https://docs.qualcomm.com/bundle/publicresource/80-70022-3SC/topics/access-content-from-the-device.md)