Lichee RV Dock Smoke 前问题清单¶
范围:StarryOS 在 Lichee RV Dock 冒烟测试完成前遇到的主要问题、症状与根因边界。 日期:2026-06-30 关联:
docs/lichee-adaptation-prework.md、docs/lichee-smoke-solutions.md、docs/licheerv-dock-bringup.md。
问题分层¶
Smoke 前的问题按根因分五层:
- 镜像尺寸
- 启动协议
- 平台链接
- 页表属性
- 错误设备假设
每一层失败都会表现为"板子没跑起来",但排查方法不同。把这些问题混在一起,会导致不断重烧镜像却没有定位进展。
表 1 按层级列出主要症状。它是排障时的分类索引,不是解决方案表。
| 层级 | 典型症状 | 初步判断 |
|---|---|---|
| 镜像尺寸 | dd 写 boot 分区报 No space left on device |
产物超过 boot 分区 |
| 启动协议 | U-Boot Starting kernel ... 后无 StarryOS 输出 |
boot image 或 axplat 入口错误 |
| 平台链接 | 链接缺 __IrqIf_* 等符号 |
D1 axplat interface 不完整 |
| 页表属性 | Store/AMO access fault |
C906 memory attribute 缺失 |
| 设备假设 | No block device found!、PCI 常量缺失 |
QEMU fs/block/PCI 假设泄漏到 D1 |
Smoke 前的主要目标:让最小 payload 在 D1 上稳定打印并停机。任何超出 early boot 的功能应先关掉。
镜像尺寸与 boot 分区限制¶
第一次替换 boot 时出现 No space left on device。根因是 StarryOS boot image 未关闭 DWARF,产物达 25.6M;官方 boot 分区备份约 10.1M。问题与内核代码正确性无关,属于镜像产物约束。
当前 Makefile 的 lichee、lichee-kbench、lichee-userbench 都显式传入 DWARF=n,证据见 Makefile:60-82。smoke 镜像最终 kernel_size = 118976 bytes,远低于 boot 分区;kbench/userbench 也保持在可写范围内。
真板适配必须先建立产物尺寸 gate。否则 U-Boot、内核入口、页表是否正确都没有机会被验证。
启动协议与平台入口不匹配¶
Lichee 官方 U-Boot 期望 Android boot image,并使用 name d1-nezha、kernel load 0x40200000、page size 2048。若 StarryOS 按 QEMU axplat 或普通 ELF/裸 bin 思路组织启动,U-Boot 可显示 Starting kernel ...,但 StarryOS 不会进入正确的平台入口。
D1 平台事实后集中到 kernel/src/platform/lichee_d1.rs:19-47,其中 BootKind::AndroidImage、load_paddr = 0x40200000、UART0 0x02500000 是 smoke 成功的前提。Makefile:60-66 负责把 smoke kernel 打包为 Android boot image。
启动协议问题的特征:U-Boot 看似正常,但 OS 没有可信输出。此时应先检查 boot image header 和 axplat,而不是用户态或 rootfs。
D1 axplat interface 缺口¶
StarryOS runtime 期望 platform 提供 console、power、irq、init、time 等接口。早期 D1 路径只让 lichee-d1 feature 进入 StarryOS entry,但没有完整替换 QEMU axplat,也没有补齐必要接口,因此出现过链接缺 __IrqIf_register、__IrqIf_set_enable、__IrqIf_handle 等问题。
根因是 feature 与 platform package 不等价。必须通过 MYPLAT=axplat-riscv64-lichee-d1、D1 axconfig.toml、platform interface 实现共同切换,不能只靠 StarryOS 内部 entry 分支。
D1 init 落到 crates/axplat-riscv64-lichee-d1/src/init.rs:1-30:early init 初始化 trap、console、time;later init 按 feature 初始化 IRQ。
axplat 缺口属于链接和接口层问题,发生在运行前。不能靠真板日志定位,只能靠构建错误和 platform interface 边界来修。
C906 页表属性问题¶
Smoke 阶段最关键的运行时 fault 是 Store/AMO access fault,符号化后指向 percpu::imp::init 中对 .bss 的 AMO 写。fault 不是 UART、USB、SD 卡或 rootfs 问题,而是 D1/C906 页表属性缺少 T-Head normal-memory SH|B|C bits。
修复须分两步,都需要 C906 属性:
- early DDR identity/high-half mapping
- 最终 kernel address space
只修 early mapping,系统会推进到更后面,但仍可能在最终页表阶段访问全局数据时 fault。
C906 memory attribute 是 D1 平台正确性的必要条件。遇到 AMO fault 时应先符号化 EPC/TVAL,确认是否页表属性,再查外设。
QEMU 设备假设泄漏¶
Smoke 阶段必须禁用 fs、block、net、display、axdriver、PCI、task-ext 等与最小启动无关的模块。D1 没有 QEMU virtio block,也没有 PCI ECAM。若沿用 QEMU feature set,会出现 No block device found!、缺失 PCI_ECAM_BASE / PCI_RANGES / PCI_BUS_END,或访问 phys_to_virt(0)。
D1 axconfig 中 virtio-mmio-ranges = [] 是关键细节,证据见 crates/axplat-riscv64-lichee-d1/axconfig.toml:17-28。不能用 [[0,0]] 占位——这会被驱动当成有效 MMIO range,并访问物理地址 0。
Smoke 策略:只打开能证明 boot 的功能。所有 QEMU 专有设备假设都应延后,直到有对应 D1 驱动或最小替代路径。
问题边界表¶
表 2 将 smoke 前问题与"不应优先排查的方向"对应起来,用于防止在错误层级消耗时间。
| 症状 | 高概率根因 | 不应优先归因 |
|---|---|---|
| boot 写入失败 | 镜像超过 boot 分区 | UART、页表、rootfs |
| U-Boot 后无 StarryOS | boot image / axplat 入口 | benchmark、syscall |
| 链接缺 platform symbol | D1 axplat interface 缺失 | 真板硬件损坏 |
| AMO fault | C906 PTE 属性 | USB、SD 卡 |
No block device found! |
误启用 block/fs | boot image header |
| PCI 常量缺失 | axdriver default PCI | D1 PLIC |
fault VA 0xffffffc000000000 |
virtio-mmio-ranges = [[0,0]] |
UART base 错 |
Smoke 前问题的共同规律:先削减运行面,再逐层打开。只有最小路径稳定后,才应讨论 PLIC、TTY、benchmark、rootfs。