Appearance
K3 + StarryOS 启动与运行缓慢问题排查
本周继续调查了 K3 COM260 真板上 StarryOS 启动及运行缓慢的问题。虽然目前已经打通了 StarryOS、J-Link、OpenOCD、GDB 和 ARD 的基本调试链路,但从系统启动到进入 Shell 仍然需要几分钟,部分简单命令执行也比较慢,影响了日常调试效率。
这次主要完成了三项工作:验证日志输出对启动性能的影响、定位并优化 CPU→hart 映射中的重复设备树查询,以及初步排查文件系统相关耗时。
1. 首先验证内核日志太多导致启动缓慢
一开始,我们怀疑 StarryOS 在启动过程中输出了大量内核日志,串口打印可能占用了较多时间。
分别构建了两组 A/B StarryOS 镜像:
- Info 组:保留普通 Info 级别的内核日志。
- Warn 组:过滤 Info 日志,仅保留 Warn 及更高等级的日志。
两组镜像使用相同的启动链及 CPU→hart 映射缓存实现,仅调整内核日志等级。在 K3 真板上共完成了 4 次有效启动测试,Info 和 Warn 各 2 次。
| 测试 | 日志等级 | Welcome → Shell | UART 输出量 |
|---|---|---|---|
| A1 | Info | 263.22 秒 | 84,920 B |
| B1 | Warn | 260.19 秒 | 26,249 B |
| B2 | Warn | 260.24 秒 | 26,252 B |
| A2 | Info | 263.41 秒 | 84,949 B |
从结果可以看到,Warn 模式下 UART 输出量减少了约 69%,但 Welcome 到 Shell 的平均耗时只减少了约 3.1 秒。四次有效测试都能正常进入 Shell,两组各自的测试结果也比较接近。
这说明,减少普通内核日志确实能降低串口输出量,但无法消除系统长达四分多钟的启动等待。现有结果不支持将启动缓慢主要归因于 Info 日志打印。
因此后续把重点转向了实际的内核执行路径。
2. 进一步定位:CPU→hart 映射反复查询设备树
在排查系统调用和进程创建过程时,发现 K3 多核处理器发送 IPI(处理器间中断)时,需要将逻辑 CPU 编号转换为硬件 hart ID。
原有实现中,这个转换过程会反复遍历设备树,查找逻辑 CPU 与 hart ID 的对应关系。
问题在于,这份映射关系在启动阶段就已经能确定,但运行时仍然重复查询。当操作涉及多个 CPU,或者系统频繁执行相关路径时,就会产生额外开销。
通过分段计时发现,在一次涉及 15 个目标 CPU 的操作中,CPU 映射查询累计耗时约 307.40 ms。
针对这一问题采用了比较直接的优化方案:系统启动时建立 CPU→hart 映射缓存表,后续发送 IPI 时直接查表,不再反复遍历设备树。
这一修改不改变 CPU 与 hart 的实际对应关系,只改变映射信息的获取方式。

随后,在 K3 真板上进行了优化前后测试:
| 测试指标 | 优化前 | 优化后 |
|---|---|---|
| CPU 映射累计耗时 | 307.40 ms | 0.00146 ms |
| 完整进程创建(clone)阶段 | 624.22 ms | 0.332 ms |
/bin/true 整体内部观测耗时 | 1789.60 ms | 1135.82 ms |
测试程序均正常完成,相关多核响应检查通过。
结果说明,重复遍历设备树确实是此前内核执行路径中的一个明显性能问题,而启动时缓存 CPU→hart 映射能够有效消除这部分重复查询开销。
在此前完整启动的阶段性对照中,Welcome 到 root Shell 的等待时间也观察到了约 43 秒的改善。

3. 优化后仍然需要四分多钟
虽然 CPU→hart 映射问题已经得到改善,但后续的 Info/Warn 实验也证明,优化后的 StarryOS 从 Welcome 到 Shell 仍需要约 260~263 秒。
因此继续观察了用户态初始化流程,其中几个比较明显的耗时阶段是:
| 阶段 | 典型耗时 |
|---|---|
env | 约 34 秒 |
touch | 约 5~6 秒 |
cat | 约 5 秒 |
此外,登录 Shell 的初始化过程中还会反复执行 grep、head、dash 等程序,这些操作累计消耗了较多时间。
继续检查相关执行路径时,发现,部分用户态程序在文件关闭阶段存在较明显的开销,涉及 ext4 文件系统元数据处理及块设备读写;UFS 相关读取路径也存在一定的累计耗时。
不过,目前的证据还不能直接说明这些耗时全部由 UFS 硬件读写造成。文件操作过程中还涉及系统调用、进程调度、缓存管理以及文件系统内部逻辑,需要进一步区分。
因此,现阶段只能将文件系统及存储 I/O 视为值得继续排查的方向,尚未定位最终根因。

4. 本周结果与下一步计划
本周主要完成了两个问题的验证。
首先,通过四次真实 K3 启动实验,确认了普通内核 Info 日志虽然明显增加串口输出量,但并不是数分钟启动延迟的主要原因。
其次,通过源码分析、分段计时和真板 A/B 测试,定位并解决了 CPU→hart 映射中反复遍历设备树的问题。优化后,映射查询开销明显下降,相关进程创建路径也得到改善,完整启动时间观察到约 43 秒的阶段性缩短。
与此同时,系统仍然存在较大的用户态程序执行及文件操作开销,特别是重复执行外部命令、文件关闭、ext4 元数据处理和 UFS 访问等路径,值得后续继续分析。在此基础上,启用 ARD 异步追踪与相关断点后,又观察到了额外约 30 秒的执行延迟。后续应该追踪断点处理与低速 JTAG 通信的累计开销。