# 调试内核

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

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

## 采集串行控制台日志

串行控制台用于访问标准启动和内核日志。串行控制台允许在实时设备上进行实时调试。Qualcomm Linux 内核允许 `CONFIG_SERIAL_QCOM_GENI` 驱动程序支持 UART 和控制台。

在内核命令行参数中添加以下行：

console=ttyMSM0,115200n8
    
    # as in following line in meta-qcom-hwe/conf/machine/include/qcom-<SoC>.conf
    KERNEL_CMDLINE_EXTRA ?= "root=/dev/disk/by-partlabel/system rw rootwait console=ttyMSM0,115200n8 pcie_pme=nomsi earlycon"
    Copy to clipboard

重新编译和加载内核时：

- 按如下所示连接一根一端是 Micro USB 接口一端是 USB-A 型接口的电缆：

    - 设备 &gt; Micro USB====USB-TypeA &gt; 主机
- 要连接到主机上的设备串行端口，请使用主计算机上的串行控制台客户端。
- 您可以在串行客户端上看到串行控制台日志和其他内核日志。

有关串行控制台的更多信息，请参见 [Linux Serial Console](https://docs.kernel.org/admin-guide/serial-console.html)。

## 配置控制台日志级别

根据调试或发布软件的要求，配置内核控制台日志级别，以记录广泛或最少的日志。

使用 `/proc/sys/kernel/printk` 配置日志级别，控制出现在控制台上的日志消息。日志级别可设置为 1 到 7。

将日志级别值设置为 1 时，只会记录最低级别的日志。将日志级别值设置为 1 时，只会打印 `pr_emerg/KERN_EMERG` 日志。

将日志级别值设置为 7 时，会启用最高日志级别 `pr_info/KERN_INFO`，并将所有 printk 日志打印到控制台。

echo "1" > /proc/sys/kernel/printk
    Copy to clipboard

## 显示内核日志

要显示内核日志，请运行以下命令之一：

dmesg
    Copy to clipboard

cat /proc/kmsg
    Copy to clipboard

## 显示自启动以来的内核日志

要显示自启动以来的内核日志，请运行以下命令之一：

cat /var/log/messages
    Copy to clipboard

cat /var/log/kern.log
    Copy to clipboard

## 使用 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. 使用以下 `menuconfig` 命令禁用内核模块签名配置、`CONFIG_MODULE_SIG`：

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. 重新启动设备。

## 使用日志级别

可以使用 `/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

## 启用 SSH

在 Permissive 模式下启用安全外壳 (SSH) 以安全地访问您的主机设备。有关说明，请参阅[使用 SSH 登录](https://docs.qualcomm.com/bundle/publicresource/topics/80-70018-254/how_to.html#use-ssh)。

## 从设备中获取信息

可以从设备中检索信息，用于调试内核问题。

下表为内核命令列表：

表：内核命令列表

| 命令 | 说明 |
| --- | --- |
| $ zcat /proc/config.gz<br>    Copy to clipboard | 内核配置 (Kernel configuration) |
| $ cat /proc/cmdline<br>    Copy to clipboard | 内核命令行参数 |
| $ cat /proc/version<br>    Copy to clipboard | 内核版本 |
| $ ls /proc/device-tree<br>    Copy to clipboard | 设备上的设备树配置 |
| $ lsmod<br>    Copy to clipboard | 已加载模块 |
| $ cat /proc/interrupts<br>    Copy to clipboard | 中断状态 |
| $ cat /sys/devices/system/cpu/cpufreq/policyX/scaling_available_frequecies<br>    Copy to clipboard | 可用的 CPU 频率，其中 X = 群集 |
| $ cat /sys/kernel/debug/qcom_socinfo/chip_id<br>    Copy to clipboard | 使用 debugfs 的 chip\_id |

有关 `procfs` 的更多信息，请参见 [The /proc Filesystem](https://docs.kernel.org/filesystems/proc.html)。

## 启用 debugfs

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

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

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

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

## 通过 KGDB 调试内核和模块

内核 GNU 调试器 (KGDB) 为设备上的内核提供实时调试支持。

可将 KGDB 配置为调试内核和模块问题。KGDB 是与 GDB 配合使用的源代码级调试工具，用于调试 Qualcomm Linux 内核。

有关 KGDB 内核调试的更多信息，请参阅 [Debugging kernel and modules via gdb](https://www.kernel.org/doc/html/v6.14-rc7/process/debugging/gdb-kernel-debugging.html)。

### 使用 KGDB 通过串行 COM 端口调试

在内核配置文件中启用以下内核驱动程序，以支持 KGDB 通过串行 COM 端口调试：

CONFIG_FRAME_POINTER
    CONFIG_KGDB
    CONFIG_KGDB_SERIAL_CONSOLE
    CONFIG_HAVE_ARCH_KGDB
    CONFIG_CONSOLE_POLL
    CONFIG_MAGIC_SYSRQ
    Copy to clipboard

更新用于调试的命令行：

# Append  KERNEL_CMDLINE_EXTRA in meta-qcom-hwe/conf/machine/include/qcom-<SoC>.conf with following string
    "kgdboc=ttyMSM0,115200n8 kgdbwait nokaslr"
    
    # If waiting during the boot of kernel for gdb connection is not desired,
    # the parameter 'kgdbwait' can be skipped.
    Copy to clipboard

**禁用看门狗**

- 在使用 KGDB 调试时禁用看门狗。当看门狗启用时，SoC 会重置。
- 要禁用看门狗，请添加以下内核命令行参数：

echo 1 > /sys/bus/platform/devices/hypervisor:qcom,gh-watchdog/disable
        Copy to clipboard

**进入调试模式的方法**

**方法 1** - 使用 `kgdbwait`：

如果将 `kgdbwait` 作为命令行参数传递，内核将执行以下操作：
1. 在启动过程中暂停执行
2. 进入调试模式
3. 等待远程 GDB 连接，并显示以下消息：

[ 0.239669] printk: console [ttyMSM0] enabled
    [ 1.535669] random: fast init done
    [ 1.541411] KGDB: Registered I/O driver kgdboc
    [ 2.224804] KGDB: Waiting for connection from remote gdb...
    Copy to clipboard

通过配置禁用看门狗。

**方法 2** - 使用 `Magic SysRq`：

要进入调试模式，请在 shell 中运行 `SysRq-G`，并运行以下命令：

`echo g > /proc/sysrq-trigger`

**方法 3** - 每当需要在源代码中触发 KGDB 断点时，在目标驱动文件中添加以下代码片段：

#include <linux/kgdb.h>   (you may need to include this file )
    kgdb_breakpoint(); //call this for adding a break point at compile time
    Copy to clipboard

**方法 4** - 触发 panic：当发生异常时，内核自动进入调试模式。要触发崩溃，请使用 `Magic SysRq` 功能。

`echo c > /proc/sysrq-trigger`

### 使用 GDB 经由 COM 端口连接 Qualcomm SoC

安装 GDB `gdb-multiarch: mingw64\bin\gdb-multiarch.exe`。

- Windows 版 GDB - 通过 [MSYS2](https://www.msys2.org/) 安装 Mingw-w64。
- Linux 版 GDB - 使用 [How to Install GDB](https://www.gdbtutorial.com/tutorial/how-install-gdb) 中的方法安装 GDB。
- 当使用 GDB 经由 COM 端口连接 SoC 时，请关闭所有其他串行端口连接。
- 在 Windows 主机上，将 COM 端口号设置为大于 16 的数字。可以从设备管理器中获取端口号。
- 在 Windows 主机上，将 COM 端口作为 `\\.\com<#>` 传递。
- 在以下示例中，从 Windows 主机的串行端口建立连接：使用的串行端口号为 COM17。在重新连接 PuTTY 之前，需要先断开 GDB 与 COM 端口的连接。若要连接和断开 GDB，可运行以下命令：

gdb-multiarch.exe -b 115200 <path_to_vmlinux>
        (gdb) target remote \\.\com17
           Remote debugging using \\.\com17
           warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread
           [Switching to Thread -2]
           arch_kgdb_breakpoint () at arch/arm64/include/asm/kgdb.h:21
           21      arch/arm64/include/asm/kgdb.h: No such file or directory.
        Copy to clipboard

要设置断点、查看断点或检查 CPU 寄存器，请运行以下命令：

# backtrace:
    > bt
    
    # set a break point:
    break <function_name>
    or
    break <filename>: line no
    
    # View all current break points:
    info break
    
    # View CPU registers:
    info reg
    
    # step over:
    s
    
    # continue execution:
    c
    Copy to clipboard

### 使用 KGDB 调试内核模块

KGDB 是一个内核补丁，允许使用 GDB 接口对正在运行的 Qualcomm Linux 内核进行源代码级调试。

您必须有 `.ko` 文件和 `.text` 内核模块文件的位置。

若要获取已加载模块 `.text` 部分的地址，可运行以下命令：

# from live device
    # cat /sys/module/<module>/sections/.text
    Copy to clipboard

若要添加模块符号文件，可运行以下命令：

(gdb) add-symbol-file <path_to_.ko> <.text_addr>
    Copy to clipboard

例如，`add-symbol-file /sys/modules/linux/linux.ko 0xc0ae22d0`。

## Ftrace

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

有关 ftrace 的更多信息，请参见[函数跟踪](https://docs.qualcomm.com/bundle/publicresource/topics/80-70018-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

### Kprobes

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

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

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

## 从用户空间配置 GPIOS

使用用户空间的 `libgpiod` 库来控制 GPIOS，以获得更佳性能。

1. 要从主机编译和推送 `libgpiod` 库，请执行以下操作：

    1. 要安装 Arm^®^ (Arm64) 工具链，请运行以下命令：

sudo apt install gcc-aarch64-linux-gnu
            Copy to clipboard

sudo apt install binutils-aarch64-linux-gnu
            Copy to clipboard
    2. 要从 [libgpiod 1.6.4.tar.xz](https://www.kernel.org/pub/software/libs/libgpiod/libgpiod-1.6.4.tar.xz) 下载并提取 libgpiod 源代码，请运行以下命令：

wget https://www.kernel.org/pub/software/libs/libgpiod/libgpiod-1.6.4.tar.xz
            Copy to clipboard

tar xvf libgpiod-1.6.4.tar.xz
            Copy to clipboard

cd libgpiod-1.6.4
            Copy to clipboard
    3. 要配置静态链接的源代码，请运行以下命令：

./configure --enable-tools=yes --build x86_64-pc-linux-gnu --host aarch64-linux-gnu CFLAGS="-static -static-libgcc -Wl,-static,--start-group,/usr/lib/gcc-cross/aarch64-linux-gnu/7.5.0/libgcc.a,/usr/lib/gcc-cross/aarch64-linux-gnu/7.5.0/libgcc_eh.a,/usr/aarch64-linux-gnu/lib/libc.a,--end-group"
            Copy to clipboard
    4. 要编译库，请运行以下命令：

make
            Copy to clipboard

Note

编译会创建链接后的二进制文件。
    5. 要编译静态链接的二进制文件，请运行以下命令：

aarch64-linux-gnu-gcc -static -o tools/gpiodetect tools/gpiodetect.o tools/tools-common.o -Wl,-L<ABSOLUTE_PATH_TO_LIBGPIOD>/libgpiod-1.6.4/lib/.libs,-lgpiod,-lpthread,-static
            Copy to clipboard

aarch64-linux-gnu-gcc -static -o tools/gpioget tools/gpioget.o tools/tools-common.o -Wl,-L<ABSOLUTE_PATH_TO_LIBGPIOD>/libgpiod-1.6.4/lib/.libs,-lgpiod,-lpthread,-static
            Copy to clipboard

aarch64-linux-gnu-gcc -static -o tools/gpioset tools/gpioset.o tools/tools-common.o -Wl,-L<ABSOLUTE_PATH_TO_LIBGPIOD>/libgpiod-1.6.4/lib/.libs,-lgpiod,-lpthread,-static
            Copy to clipboard

aarch64-linux-gnu-gcc -static -o tools/gpiofind tools/gpiofind.o tools/tools-common.o -Wl,-L<ABSOLUTE_PATH_TO_LIBGPIOD>/libgpiod-1.6.4/lib/.libs,-lgpiod,-lpthread,-static
            Copy to clipboard

aarch64-linux-gnu-gcc -static -o tools/gpioinfo tools/gpioinfo.o tools/tools-common.o -Wl,-L<ABSOLUTE_PATH_TO_LIBGPIOD>/libgpiod-1.6.4/lib/.libs,-lgpiod,-lpthread,-static
            Copy to clipboard

aarch64-linux-gnu-gcc -static -o tools/gpiomon tools/gpiomon.o tools/tools-common.o -Wl,-L<ABSOLUTE_PATH_TO_LIBGPIOD>/libgpiod-1.6.4/lib/.libs,-lgpiod,-lpthread,-static
            Copy to clipboard
2. 要在编译后将二进制文件推送到设备，请运行 `scp` 命令。例如：

scp gpioinfo root@<IP_address>:/path/to/directory/on/device
        Copy to clipboard

将二进制文件推送到设备后，在设备上运行以下命令以与 GPIO 交互：

1. 使用 `gpiodetect` 和 `gpioinfo` 命令列出 GPIO 芯片和线路。以下示例展示了 GPIO 芯片信息：

sh-5.2# ./gpiodetect
        gpiochip0 [c440000.spmi:pmic@8:pinctrl@c00] (12 lines)
        gpiochip1 [c440000.spmi:pmic@1:gpio@8800] (10 lines)
        gpiochip2 [c440000.spmi:pmic@2:gpio@8800] (9 lines)
        gpiochip3 [c440000.spmi:pmic@0:gpio@b000] (4 lines)
        gpiochip4 [f100000.pinctrl] (176 lines)
        gpiochip5 [33c0000.pinctrl] (15 lines)
        Copy to clipboard

    以下示例显示了 GPIO 线路：

sh-5.2# ./gpioinfo gpiochip5
        gpiochip5 - 15 lines:
              line    0:      unnamed       unused   input   active-high
              line    1:      unnamed       unused   input   active-high
              line    2:      unnamed       unused   input   active-high
              line    3:      unnamed       unused   input   active-high
              line    4:      unnamed       unused   input   active-high
              line    5:      unnamed       unused   input   active-high
              line    6:      unnamed       unused   input   active-high
              line    7:      unnamed       unused   input   active-high
              line    8:      unnamed       unused   input   active-high
              line    9:      unnamed       unused   input   active-high
              line   10:      unnamed       unused   input   active-high
              line   11:      unnamed       unused   input   active-high
              line   12:      unnamed       unused   input   active-high
              line   13:      unnamed       unused   input   active-high
              line   14:      unnamed       unused   input   active-high
        Copy to clipboard
2. 使用 `gpioset` 命令设置 GPIO 值。例如，要在 `gpiochip4` 上设置 `GPIO line 0`，请执行以下操作：

sh-5.2# ./gpioset gpiochip4 0=1
        sh-5.2# ./gpioinfo gpiochip4
        gpiochip4 - 176 lines:
           line    0:      unnamed       unused   output  active-high
           line    1:      unnamed       unused   input   active-high
        Copy to clipboard
3. 使用 `gpioget` 命令读取 GPIO 值。例如，要在 `gpiochip4` 上读取 `GPIO line 0` 的值，请执行以下操作：

sh-5.2# ./gpioget gpiochip4 0
        1
        sh-5.2# ./gpioinfo gpiochip4
        gpiochip4 - 176 lines:
                 line    0:      unnamed       unused   input   active-high
                 line    1:      unnamed       unused   input   active-high
        Copy to clipboard

## 排查内核问题

要排查内核问题，请使用以下方法：

### 选错/没有可用的 DTB 导致启动失败

排查因 DTB 加载问题而导致的启动失败时，需要验证鉴权及 DTB 可用性，然后按以下步骤解决问题。

如下场景会导致启动失败：

- **身份验证失败**

    以下示例所示为因鉴权错误而导致的启动失败的日志：

Platform Subtype : 0
        DtPlatformLoadDtb qcs6490-rb3gen2.dtb is loaded
        Platform Subtype : -2090817768
        DtPlatformLoadSign qcs6490-rb3gen2.sgn is loaded
        failed to authenticate image !
        Copy to clipboard
- **由于 DTB 不可用导致失败**

    以下示例所示为因缺少 DTB 而导致的启动失败的日志：

DtPlatformLoadDtb qcs6490-rb3gen2.dtb is loading failed with Status = E
        DtPlatformDxeEntryPoint: no DTB blob could be loaded, defaulting to ACPI (Status == Not Found)
        Copy to clipboard

    要修复 DTB 不可用问题，请执行以下步骤：

    - 验证相应的 DTB 文件是否包含在打包的 `efi.bin` 文件中
    - 在主机开发机器本地挂载 `efi.bin` 文件以验证以下内容：

mount -t vfat efi.bin /mnt/
            
            ls -lR /mnt/
            Copy to clipboard

### 串行控制台不工作

若要排查串行控制台日志失败问题，需在内核配置中启用特定的驱动程序并将相关参数添加到内核启动参数中。

- 在内核配置文件中启用以下驱动程序：

    - `CONFIG_SERIAL_QCOM_GENI=y`
    - `CONFIG_SERIAL_QCOM_GENI_CONSOLE=y`
- 将以下参数添加到内核启动参数中：

console=ttyMSM0,115200n8
        Copy to clipboard
- 若要从内核获取早期启动消息，需将以下参数添加到内核启动参数中：

earlycon
        Copy to clipboard

### 调试 Remoteproc 失败

要排查 remoteproc 故障，请采集内核日志、使用匹配的固件签名文件并验证设备中的固件位置。

- 确保所有匹配的子系统镜像均已无错误刷写。
- 验证内核日志中是否存在任何错误。

    以下所示为内核日志示例：

0x000000000A27652C |   5198.790423:   qcom_q6v5_pas 3000000.remoteproc: fatal error received: err_inject_crash.c:413:Crash injected via Diag
        0x000000000A276689 |   5198.801061:   remoteproc remoteproc2: crash detected in 3000000.remoteproc: type fatal error
        0x000000000A2767A1 |   5198.809602:   remoteproc remoteproc2: handling crash #1 in 3000000.remoteproc
        0x000000000A27688E |   5198.816837:   remoteproc remoteproc2: recovering 3000000.remoteproc
        0x000000000A276971 |   5198.823784:   qcom_q6v5_pas 8a00000.remoteproc: subsystem event rejected
        Copy to clipboard
- 禁用以下子系统重启功能，确保 remoteproc 崩溃签名显示在内核日志中：

echo disabled > /sys/kernel/debug/remoteproc/remoteprocN/recovery
        Copy to clipboard
- 确认所有必要的固件文件是否在 `/lib/firmware/qcom/<SoC> in rootfs` 文件系统中。

### 调试配置或符号未反映在镜像中

要调试配置或符号未在镜像中体现的内核配置更改问题，请执行以下步骤：

- 将调试配置驱动程序添加到 `arch/arm64/configs/qcom_debug.config` 文件。
- 在运行 `bitbake` 命令前导出 `DEBUG_BUILD=1` 宏。

Note

旧的调试配置文件与定制 BSP 版本有关。将更改添加到基本 BSP 变体的 `qcom.cfg` 文件中。

### 系统内存不足

要调试系统可用内存耗尽的情况，请参见[内存不足](https://docs.qualcomm.com/bundle/publicresource/topics/80-70018-12/debugging_linux_kernel.html#out-of-memory)。

### 在启动过程中识别 DTB

设备启动时，boot loader 会验证以下 ID 并加载相应的 DTB 文件：

qcom,msm-id = <x z>;
    qcom,board-id = <y y'>;
    Copy to clipboard

- x = ID for SoC
- z = ID for SoC revision (reserved field)
- y = CDP、MTP（硬件变体）和平台的 ID
- y’ = 子类型的 ID（若不存在则假定为 0）

### 排查 virtio 问题

使用以下方法排查 virtio 问题：

- 确保内核已按所需配置编译。
- 验证 QEMU 命令行选项或 libvirt XML 配置。
- 核实系统日志中是否存在错误。
- 在 QEMU 命令行中使用可用的跟踪后端为 virtio 启用跟踪功能。有关 KVM 跟踪的更多信息，请参阅 [KVM 跟踪](https://docs.qualcomm.com/doc/80-70018-3SC/topic/virtualization.html#kvm-traces)。

Last Published: May 05, 2025

[Previous Topic
自定义内核](https://docs.qualcomm.com/bundle/publicresource/80-70018-3SC/topics/customize.md) [Next Topic
参考资料](https://docs.qualcomm.com/bundle/publicresource/80-70018-3SC/topics/references.md)