> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs-staging.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"
```
