> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 内核日志

内核日志消息是诊断启动失败、驱动问题和运行时错误的主要信息来源。本页介绍如何将这些消息从设备中获取:通过串行控制台、早期启动控制台、运行时日志命令以及日志级别控制。

## 串行控制台

Qualcomm<sup>®</sup> Linux 内核使用 Qualcomm 通用接口(GENI)串行驱动,在 Qualcomm SoC 上支持 UART 控制台。

### 所需的内核配置

验证以下 Kconfig 选项已启用:

```bash theme={null}
zcat /proc/config.gz | grep -E "CONFIG_SERIAL_QCOM_GENI"
# Expected:
# CONFIG_SERIAL_QCOM_GENI=y
# CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
```

如果缺少任何一项,请在内核 defconfig 或 `.cfg` 片段中启用它们并重新构建。

### 将串行控制台添加到内核命令行

在 `meta-qcom/conf/machine/include/qcom-<SoC>.conf` 的 `KERNEL_CMDLINE_EXTRA` 中添加 `console=` 参数:

```text theme={null}
KERNEL_CMDLINE_EXTRA ?= "root=/dev/disk/by-partlabel/system rw rootwait \
                          console=ttyMSM0,115200n8 pcie_pme=nomsi earlycon"
```

| **参数**                     | **含义**                                                 |
| :------------------------- | :----------------------------------------------------- |
| `console=ttyMSM0,115200n8` | 将内核日志输出路由到第一个 Qualcomm GENI UART,波特率 115200,无校验,8 位数据位 |
| `earlycon`                 | 在驱动初始化之前启用早期控制台(见下文)                                   |

### 连接硬件

在设备与主机之间连接 USB 转 UART 线缆:

```text theme={null}
Device UART header → USB-UART adapter → Host USB port
```

在主机上,使用任意终端仿真器(minicom、screen、PuTTY 或 Tera Term)以 115200 波特率打开串行端口:

```bash theme={null}
# Linux example
minicom -D /dev/ttyUSB0 -b 115200
```

有关上游文档,请参阅
[Linux Serial Console](https://docs.kernel.org/admin-guide/serial-console.html)。

## 早期启动消息(earlycon)

`earlycon` 内核参数在完整 UART 驱动初始化之前启用一个最小化的早期控制台。它提供从启动序列最开始的内核消息,包括 initramfs 的解包和早期设备树处理,这些消息否则将不可见。

添加到内核命令行:

```text theme={null}
earlycon
```

在 Qualcomm SoC 上,早期控制台使用相同的 `ttyMSM0` UART。消息从 `start_kernel()` 的第一行开始立即显示。

<Note>
  `earlycon` 和 `console=ttyMSM0,...` 是相互独立的。同时使用两者可以获得从早期启动到登录提示符之间不间断的输出。
</Note>

## printk 日志级别

`printk` 是内核的日志函数。每条消息都带有一个日志级别,控制它是否显示在控制台上。

**表:printk 日志级别**

|   **级别**  | **宏**                       | **数值** | **含义**   |
| :-------: | :-------------------------- | :----: | :------- |
| Emergency | `pr_emerg` / `KERN_EMERG`   |    0   | 系统不可用    |
|   Alert   | `pr_alert` / `KERN_ALERT`   |    1   | 必须立即采取行动 |
|  Critical | `pr_crit` / `KERN_CRIT`     |    2   | 危急状况     |
|   Error   | `pr_err` / `KERN_ERR`       |    3   | 错误状况     |
|  Warning  | `pr_warn` / `KERN_WARNING`  |    4   | 警告状况     |
|   Notice  | `pr_notice` / `KERN_NOTICE` |    5   | 正常但重要的状况 |
|    Info   | `pr_info` / `KERN_INFO`     |    6   | 信息性消息    |
|   Debug   | `pr_debug` / `KERN_DEBUG`   |    7   | 调试级别消息   |

数值低于当前控制台日志级别的消息会打印到控制台。Qualcomm Linux 上默认的控制台日志级别为 7(打印所有消息)。在默认控制台日志级别为 7 的情况下,级别 0–6(Emergency 到 Info)的消息会到达控制台。将级别设置为 8 可包含调试输出。

### 运行时日志级别控制

通过 `/proc/sys/kernel/printk` 在运行时读取和设置控制台日志级别。
该文件包含四个以空格分隔的值:
`<current> <default> <minimum> <boot-time-default>`。

```bash theme={null}
# Read current log level
cat /proc/sys/kernel/printk
# Example output: 7  4  1  7

# Set console log level to 4 (warnings and above only)
echo "4" > /proc/sys/kernel/printk

# Suppress all but emergencies (useful for release/performance tests)
echo "1" > /proc/sys/kernel/printk
```

### 启动时日志级别

在内核命令行上设置日志级别,以在 `/proc` 挂载之前控制详细程度:

```text theme={null}
loglevel=4      # warnings and above
quiet           # equivalent to loglevel=4 with reduced output
loglevel=0      # silence all output (only KERN_EMERG passes)
```

## 读取内核日志缓冲区

### dmesg

读取内核环形缓冲区最常用的方式:

```bash theme={null}
dmesg                         # full buffer
dmesg | head -50              # first 50 lines (early boot)
dmesg | tail -50              # most recent 50 lines
dmesg --level=err,warn        # errors and warnings only
dmesg -T                      # human-readable timestamps
dmesg -w                      # follow (like tail -f)
```

### /proc/kmsg

提供内核消息实时流的虚拟 proc 文件。每次读取只返回新消息:

```bash theme={null}
cat /proc/kmsg   # streams kernel log (Ctrl+C to stop)
```

### 跨重启的持久化日志

在运行 systemd-journald 的系统上,内核消息会被持久化存储,并可跨启动查询:

```bash theme={null}
journalctl -k           # kernel messages from the current boot
journalctl -k -b -1     # kernel messages from the previous boot
```

在没有 journald 的系统上,内核消息可能会写入 syslog 文件:

```bash theme={null}
cat /var/log/kern.log    # Debian/Ubuntu style
cat /var/log/messages    # RHEL/embedded style
```

## 禁用控制台日志

在生产环境或性能测试中让控制台静默:

```text theme={null}
# Kernel command-line options (choose one):
quiet                    # suppress informational messages
console=null             # discard all console output
loglevel=0               # only KERN_EMERG messages pass
```

或者,在 Kconfig 中禁用早期控制台驱动,以获得完全静默的构建:

```text theme={null}
# CONFIG_SERIAL_EARLYCON is not set
# CONFIG_SERIAL_MSM_CONSOLE is not set
```

## 调试构建

要在 Yocto 镜像中包含调试符号和额外的调试 Kconfig,请在 bitbake 调用时传递 `DEBUG_BUILD=1`。这会在内核构建中启用 `debug.config` 片段:

```bash theme={null}
# Inside the kas shell
DEBUG_BUILD=1 bitbake qcom-multimedia-image
```

或者将其永久添加到 `build/conf/local.conf`:

```text theme={null}
DEBUG_BUILD = "1"
```
