W03 - Q19B userbench → Q19C 全链路收尾¶
周期:2026-07-05 ~ 2026-07-11
分支:
uart-16550-lichee(领先 origin 10 commits)提交数:20 个
代码定位:commit 链接用短 SHA 7 位;M0 段指向 HEAD
217fdd7,M1/M2/M3 段指向 HEAD6998e09
本周工作¶
下面的那些还是过于晦涩、繁复了,简单总结如下: 1. 一边做,一边解决了不少问题 2. 重新写了测试代码,分别在qemu和真板上面运行 3. 探索代码,取消了一些原定的但是与异步串口工作无关的开发方向
下周(后续)工作¶
在收集完真板的各种数据参数之后做了简单的分析,下周可能会做: 1. 当前异步串口驱动表现优秀,反而是真板线速成为了限制,评价为驱动是5g驱动,设备是2g设备,我现在是想探索dma方向 2. 等待另一个板子
上下文¶
阶段一+二(Q16-Q19 smoke)已在真板输出 [starry-d1] smoke complete, halting.。本文记录:阶段三(Q19B)benchmark 交付、阶段四(Q19C-M0)evidence cleanup、Q19C-M1 memory-root path loader、M2 command-entry、M3 收尾与 closeout。
阶段三目标:在真板跑通 embedded benchmark.elf,验证 /dev/console、TTY、syscall、tcdrain、FIONBIO 全链路。
阶段四目标:统一 QEMU/D1 benchmark manifest,消除测量污染,通过 memory-root 路径完成 D1 真板全链路 benchmark 验证,正式结束 D1 async UART 测试。
详见 weekly-2026-W02 的 Q19 smoke 收尾状态。
阶段二延伸:硬件能力 + 运行模式拆分¶
阶段二结尾发现用户态运行时(/dev/console、syscall、task-ext)被 lichee-d1-smoke / lichee-d1-kbench 的模块排除规则误伤。Q19B 在阶段二基础上重新做 feature 拆分(ADR-050):
| 类别 | feature | 作用 |
|---|---|---|
| 平台 smoke | lichee-d1 |
smoke 回归(保持向后兼容) |
| 硬件能力 | lichee-d1-async-uart |
DW APB UART stride 4 + 真 PLIC |
| 运行模式 | lichee-d1-kbench |
kernel benchmark 后 halt |
| 运行模式 | lichee-d1-userbench |
含 axfs/pseudofs/syscall 的最小用户态 runtime |
# kernel/Cargo.toml:14-18
lichee-d1 = []
lichee-d1-smoke = []
lichee-d1-async-uart = [] # 硬件能力(DW APB UART + PLIC)
lichee-d1-kbench = ["lichee-d1-async-uart"] # 运行模式:kernel benchmark 后 halt
lichee-d1-userbench = ["lichee-d1-async-uart", "dep:axfs", "axfeat/paging", "axfeat/task-ext"]
kbench 的模块排除不影响 userbench。
阶段三实施(Q19B 2026-06-29)¶
- DW APB UART 32-bit MMIO UartPort(ADR-048):新文件
kernel/src/drivers/d1_uart.rs(162 行)实现ArceOsD1UartPort。内部用 stride-awareread_reg(offset)/write_reg(offset, val)封装base_ptr.add(offset * stride).cast::<u32>().read_volatile()。复用AsyncUartDriver类型系统与uart_16550::async_::isr的RX_WAKER/TX_WAKER/DRAIN_WAKER(c820567)。 - axfs-ng 本地 patch(ADR-049):
crates/axfs-ng/Cargo.toml改axdriver依赖,强制block + bus-mmio(e7d1933)。 - embedded benchmark ELF loader:在
kernel/src/mm/loader.rs:357新增load_embedded_user_app()。通过include_bytes!嵌入kernel/resources/benchmark.elf,绕过文件系统(解析 ELF → 分配用户映射 → uspace.write())(4ba2f75)。
踩坑 6:feature 继承导致 userbench 编译失败¶
症状:cargo check --target riscv64gc-unknown-none-elf --features lichee-d1-userbench 报缺 crate::drivers::ASYNC_TTY、crate::file、crate::mm、crate::pseudofs、crate::task、axfs、axtask::AxTaskExt。
根因:kernel/src/lib.rs 和 kernel/src/drivers/mod.rs 用 #[cfg(not(any(feature = "lichee-d1-smoke", feature = "lichee-d1-kbench")))] 排除用户态路径模块;同时旧版本 lichee-d1-userbench = ["lichee-d1-kbench"] 让 userbench 继承会排除文件/任务/伪文件系统的 kbench-only feature。
修复:拆分硬件能力与运行模式(ADR-050),见上节 feature 表(fcb008d)。
踩坑 7:Cargo.lock 版本污染¶
症状:对 workspace 内 path dependency 执行 cargo check --manifest-path 后 Cargo.lock 中 axcpu 0.3 被升级到 0.3.1,破坏版本对齐。
根因:axcpu 在 Cargo.toml 中用 axcpu = "0.3" 松约束,被新解析自动升级。
修复:根 Cargo.toml:122 用 [patch.crates-io] axcpu = { ... } 本地锁定,并在 crates/axplat-riscv64-lichee-d1/Cargo.toml 显式 axcpu = "=0.3.0-preview.8" 精确锁死。误升级后 git restore Cargo.lock 恢复(c820567)。
踩坑 8:axdriver build.rs 输出的 cfg 绕过 axfeat 弱转发¶
症状:启用 axfeat/bus-mmio 后仍编译 axdriver/src/bus/pci.rs,链接报 PCI_ECAM_BASE 未定义。
根因:axdriver 的 build.rs 根据自身是否启用 bus-mmio feature 输出自定义 cfg:有 bus-mmio → cargo:rustc-cfg=bus="mmio";否则默认 cargo:rustc-cfg=bus="pci"。axfeat/bus-mmio = ["axdriver?/bus-mmio"] 只转发给 axfeat 自己的可选依赖 axdriver,不会影响 axfs-ng 间接拉进来的 axdriver。
修复:在本地 patch 的 crates/axfs-ng/Cargo.toml 显式写:
# crates/axfs-ng/Cargo.toml:18
axdriver = { version = "=0.3.0-preview.2", default-features = false, features = ["block", "bus-mmio"] }
(e7d1933)。
踩坑 9:embedded ELF 含 relocation¶
症状:load_embedded_user_app() 解析 kernel/resources/benchmark.elf 后在用户空间跳转到 0x0 触发 page fault。
根因:riscv64-linux-musl-gcc -static 产出 DYN / static PIE,带 R_RISCV_RELATIVE relocation;当前 loader 不做 relocation。
修复:gcc -static -no-pie -fno-pie -s;file + readelf -h + readelf -r 验证 Executable file 与 There are no relocations in this file.。load_embedded_user_app 见 kernel/src/mm/loader.rs:357:
#[cfg(feature = "lichee-d1-userbench")]
pub fn load_embedded_user_app(
uspace: &mut AddrSpace,
elf_data: &[u8],
args: &[String],
envs: &[String],
) -> AxResult<(VirtAddr, VirtAddr)> {
// ET_EXEC(base=0)路径;ET_DYN/PIE 路径不处理 relocation
let elf_parser =
ELFParser::new(&elf, crate::config::USER_SPACE_BASE).map_err(|_| AxError::InvalidData)?;
(4ba2f75)。
踩坑 10:THRE 边沿丢失导致 TX 不唤醒¶
症状:真板日志显示 PLIC 进入 UART IRQ 18,但 IIR 多次为 0xc1(bit0=1 no pending),有效 THRE 0xc2 只偶发;userbench 64B write 后 tcdrain 不返回。
根因:QEMU 会稳定触发 THRE 中断,掩盖了"启用 THRE 时硬件已 ready 但不再产生新边沿"的真板窗口。D1 ArceOsD1UartPort::update_ier(THR_EMPTY) 在 LSR 已 THRE/TEMT 时未立即软件 wake。
修复(ADR-051):D1 backend 启用 THRE 时立即软件 wake;ISR 在 IIR bit0=1 时基于 LSR 补 wake:
// kernel/src/drivers/d1_uart.rs:178
fn update_ier(&self, set: IER, clear: IER) {
let mut val = self.ier_cache.load(Ordering::Relaxed);
val |= set.bits();
val &= !clear.bits();
self.ier_cache.store(val, Ordering::Relaxed);
self.write_reg(UART_IER, val as u32);
if set.contains(IER::THR_EMPTY) {
use uart_16550::async_::isr;
let lsr = self.read_reg(UART_LSR);
if lsr & LSR_THRE != 0 { isr::TX_WAKER.wake(); }
if lsr & LSR_TEMT != 0 { isr::DRAIN_WAKER.wake(); }
}
}
// kernel/src/drivers/d1_uart.rs:198
fn d1_uart_isr_handler() {
let lsr = read_reg(UART_LSR);
if lsr & LSR_THRE != 0 { isr::TX_WAKER.wake(); }
if lsr & LSR_TEMT != 0 { isr::DRAIN_WAKER.wake(); }
if lsr & LSR_DR != 0 { isr::RX_WAKER.wake(); }
// ... IIR dispatch above
}
(d4a8b63)
踩坑 11:tcdrain 漏覆盖 staged/TEMT¶
症状:Q19B 首次跑 userbench,64B write 后 tcdrain 永久挂起;增大 wait timeout 后最终返回但耗时异常。
根因:flush()/sys_ioctl(TCSBRK) 只注册 TX ring waker,未覆盖 TX copier 已 pop 到 staged buffer 后的 staged_bytes -> 0 与 UART TEMT 变化。
修复:flush() 始终注册 DRAIN_WAKER;TX copier 在最后一批送完且 TEMT 后主动 wake drain:
// crates/uart_16550/src/async_/driver.rs:489
self.tx_staged_bytes
.fetch_sub(sent, Ordering::AcqRel);
if last_batch {
// TEMT corner-case: 主动 wake drain 等待者
DRAIN_WAKER.wake();
}
四阶段 drain 快照:
// crates/uart_16550/src/async_/driver.rs:288
pub struct TxCompletion {
pub ring_empty: bool,
pub copier_active: bool,
pub staged_bytes: usize,
pub transmitter_empty: bool,
}
impl TxCompletion {
pub fn is_drained(&self) -> bool {
self.ring_empty && !self.copier_active
&& self.staged_bytes == 0 && self.transmitter_empty
}
}
这部分后续会回写到专门的 UART 仓库。
(b1d15e3)
Q19B 阶段初步数据(2026-06-29,已被 Q19C.8e 覆盖)¶
Q19B 首次跑通 embedded userbench 时的初步数据。最新指标见阶段四(Q19C.8e)。
镜像产物:
| Make 目标 | 输出 | kernel_size |
|---|---|---|
make lichee |
starry-lichee-boot.img |
118976 bytes |
make lichee-kbench |
starry-lichee-kbench-boot.img |
188608 bytes |
make lichee-userbench |
starry-lichee-userbench-boot.img |
876736 bytes(Q19B)/ 970944 bytes(Q19C.8e) |
阶段四:Q19C-M0 benchmark evidence cleanup(2026-07-07)¶
Q19B 完成后,Q19C-M0 统一 QEMU/D1 benchmark manifest,诊断 D1 TX copier 的 hw_send_zero / no_progress_budget_exhausted / P99 长尾(7a13a46、217fdd7)。
横向对比(QEMU rootfs vs D1 userbench)¶
q19c-m0-20260703 同版用户态 benchmark 在 QEMU 与 D1 真板输出同构指标。QEMU 不仿真物理线延迟(line_rate_pct > 100% 为预期),D1 大包稳定接近 11.52 KB/s 理论线速,作绝对线速依据。
| 指标 | QEMU rootfs | Lichee D1 userbench | 解释 |
|---|---|---|---|
| TX baseline 64B drain-each | 153.86 KB/s | 11.13 KB/s | D1 达 96.6% 线速(pre-section drain 后消除 backlog 污染) |
| TX baseline 256B drain-each | 167.20 KB/s | 11.21 KB/s | D1 达 97.3% 线速 |
| TX baseline 1024B drain-each | 182.28 KB/s | 11.38 KB/s | D1 达 98.8% 线速 |
| TX batch-drain 64B | 159.34 KB/s | 11.38 KB/s | D1 64B batch-drain 达 98.8% 线速 |
| TX writev 4x64B | 149.88 KB/s | 11.36 KB/s | 两端均出现 1 字节短写 |
| TX 1B P99 | 0.357 ms | 0.224 ms | D1 1B 不触发 FIFO full |
| RX empty nonblocking | PASS | PASS | open(O_NONBLOCK) 与 ioctl(FIONBIO) 均返回 EAGAIN |
内核态 startup benchmark¶
衡量 async UART 驱动内部 ring buffer 与统计路径,不代表硬件 UART 线速。
| 指标 | QEMU rootfs | Lichee D1 userbench | 测量条件 |
|---|---|---|---|
| Ring buffer TX push | 550,055 KB/s | 1,151,569 KB/s | 102400 bytes,100 x 1024B |
| RX ring buffer read | 1,205,273 KB/s | 8,437,706 KB/s | 65536 bytes |
| RX latency P99 | 11,600 ns | 246 ns | n=100,单字节 ring pop |
| Driver struct | 152 bytes | 272 bytes | Q19C.8e 加 slow-pool/yield 计数器 |
| IRQ count at report | 0 | 43 | startup benchmark 阶段 |
D1 driver struct 从 152 bytes 增加到 272 bytes(Q19C.8e slow-pool + yield 计数器)。D1 IRQ count 43 反映 slow-pool 期间 TX_WAKER 注册后 ISR 更频繁到达。
benchmark.c 统一¶
- S00 manifest 输出 benchmark version、target mode、startup chain、root provider、TX 矩阵、RX 模式
- 移除 4096B 默认测试(缩短真板运行时间)
- 移除 S10 drain-each-recheck 和 S11 second-drain(已证明无信息量)
- S11 加 gated TX debug snapshot:
hw_send_zero/no_progress_budget_exhausted/hw_send_max_chunk/slow_poll_exh/yield_exh
64B 测量污染消除¶
旧数据 D1 64B write+tcdrain 约 1 KB/s(8.8% 线速)。根因是进入 S10 前 stdout backlog 在 D1 上 pre_section_stdout_drain_ms=5688,把 manifest/日志排空时间计入首个小包段。每节开始加 fflush(stdout); tcdrain(STDOUT_FILENO) 并打印 pre-drain。隔离后 D1 64B 达 10.7-11.1 KB/s(93-97% 线速)。
D1 TX copier 修复(Q19C.8d)¶
ArceOsD1UartPort::send_bytes()在 THRE 后一次填最多 16B FIFO(hw_send_max_chunk从 1 提到 16,S11 1024B 正确发送恢复)。- TTY OPOST/ONLCR short-write 计数修复(S11 1024B
short_writes从高数字降到 36)。
Q19C.8e slow-pool + yield 重试¶
TX copier 在 budget exhausted(32 次 fast retry 失败)后加入 bounded slow-pool(TX_SLOW_POLL_LIMIT=4096 × TX_SLOW_POLL_SPINS=256),给 FIFO 排空时间后 retry send_bytes。slow-pool 失败后再 yield 重试(TX_YIELD_RETRIES=4 自唤醒),最后才 fallback 到纯 ISR 等待。
TX_FAST_RETRY_LIMIT=0 + drain 注册 TX_WAKER 的方案已证伪——benchmark 进程启动后卡住,D1 THRE 唤醒路径不能作为唯一进展来源。
Q19C.8e 真板数据(2026-07-07)¶
三轮数据对比(S11 final-drain txdbg):
| 轮次 | size=64 hw_send_calls | hw_send_zero | no_progress_budget | slow_poll_exh | yield_exh | P99 (256B) |
|---|---|---|---|---|---|---|
| 基线 | 13,966 | 13,566 | 399 | - | - | 50.872ms |
| +slow-pool | 274,218 | 273,818 | 399 | - | - | 50.868ms |
| +yield | 274,396 | 273,996 | 399 | 0 | 0 | 50.860ms |
slow_poll_exh=0 证明 slow-pool 100% 成功(每次 budget exhausted 后约 653 次 send_bytes 后 FIFO 排空)。yield_exh=0 证明 yield 重试从未触发。P99 长尾根因未探明——slow-pool/yield 均未改善,slow_over_line_plus10ms=1(100 次中 1 次超出线时+10ms)。当前影响可接受(吞吐量 <2%),暂不继续优化。
D1 真板最终性能(Q19C.8e 后):
| 指标 | 值 |
|---|---|
| 64B TX drain-each | 11.13 KB/s(96.6% 线速) |
| 256B TX drain-each | 11.21 KB/s(97.3% 线速) |
| 1024B TX drain-each | 11.38 KB/s(98.8% 线速) |
| 64B TX batch-drain | 11.38 KB/s(98.8% 线速) |
| 1B tcdrain P99 | 0.224 ms |
| FIONBIO 双入口 | PASS |
| benchmark exit code | 0 |
镜像产物(Q19C.8e 后):
| Make 目标 | 输出 | kernel_size |
|---|---|---|
make lichee-userbench |
starry-lichee-userbench-boot.img |
983232 bytes |
Q19C.8e 产出位置¶
| 路径 | 用途 | 关键 commit |
|---|---|---|
crates/uart_16550/src/async_/driver.rs |
TX_SLOW_POLL_LIMIT/TX_SLOW_POLL_SPINS/TX_YIELD_RETRIES 常量 + slow-pool + yield 重试逻辑 + slow_poll_exhausted/yield_retries_exhausted 计数器 |
7a13a46、217fdd7 |
tests/benchmark.c |
S00 manifest + S11 gated TX debug snapshot + 移除 S10 recheck/S11 second-drain | 7a13a46、217fdd7 |
kernel/src/syscall/fs/ctl.rs |
UartTxDebugSnapshot 加 slow_poll_exhausted/yield_retries_exhausted 字段 |
217fdd7 |
阶段三产出位置¶
| 路径 | 用途 | 关键 commit |
|---|---|---|
kernel/src/drivers/d1_uart.rs |
ArceOsD1UartPort(stride 4 / 32-bit MMIO) |
c820567 |
kernel/src/drivers/d1_uart.rs:178 |
update_ier 软件 wake |
d4a8b63 |
kernel/src/drivers/uart_init.rs |
QEMU/D1 双路径 feature gate | c820567 |
crates/axfs-ng/Cargo.toml:18 |
axdriver 强制 block + bus-mmio |
e7d1933 |
kernel/src/mm/loader.rs:357 |
load_embedded_user_app() |
4ba2f75 |
kernel/src/entry.rs |
lichee_d1_init() 三模式分发 |
c820567 |
kernel/Cargo.toml:14-18 |
feature 拆分 | fcb008d |
kernel/resources/benchmark.elf |
嵌入式用户态 benchmark | 4ba2f75 |
ADR 索引(阶段三新增)¶
| ADR | 标题 | 状态 |
|---|---|---|
| ADR-047 | Q19B 先嵌入 benchmark payload,再追求 SDMMC/rootfs parity | ✅ 已接受 |
| ADR-048 | D1 先做平台专用 UartPort,后考虑 width-aware backend | ✅ 已落地 |
| ADR-049 | Q19B Phase 5-6 通过最小 axfs-ng patch 解阻 | ✅ 已落地 |
| ADR-050 | Q19B feature 必须区分硬件能力与运行模式 | ✅ 已落地 |
| ADR-051 | D1 async UART drain 必须兼容 THRE 边沿丢失 | ✅ 已落地 |
| ADR-052 | Q19C fullbench 范围收敛:M0 evidence cleanup + M1 path loader + M3 SDMMC probe-only | ✅ 已落地 |
learned 条目索引(阶段三)¶
openspec/specs/learned/spec.md:
- L236-L239:Q19B benchmark 依赖链 + async UART 首要阻塞 + PLIC 代码已存在但未启用 + embedded ELF 推荐
- L240-L244:Q19B feature 拆分方案 + DW APB UART 实现 + uart_init 双路径 + axfs 阻塞解决 + cargo check 三模式
- L245-L251:feature 继承陷阱 + 五阻塞全景 + 五步路线 + feature 规范化实战 + 最小依赖集 + embedded ELF 加载 + 最终 host gate
- L252-L258:axdriver cfg(bus) 不是普通 feature + axfeat 弱转发不能修复间接 axdriver + embedded ELF 必须禁用 PIE + THRE 边沿丢失 + tcdrain 必须覆盖 staged/TEMT + 真板性能基线 + CRLF/exit drain
- L259-L266:Q19C 路径差异 + fullbench feature 边界 + rootfs provider 分层 + benchmark 证据口径 + 64B 测量污染 + TX drain/THRE 长尾排查
- L275:Q19C.8e slow-pool + yield 重试真板验证结果(slow_poll_exh=0 证明 slow-pool 100% 成功,P99 根因未探明)
Q19C-M1:memory-root path loader(2026-07-08)¶
Q19C-M0 在 QEMU rootfs 跑通后,M1 在 D1 真板通过 memory-root 路径加载 /bin/benchmark。
实施:
- 新增 Make 目标
lichee-fullbench-mem:cp benchmark.elf disk.img挂载为 ramfs/bin/benchmark ArceOsD1App::resolve_path("/bin/benchmark")→FS_CONTEXT.resolve()→load_user_app()路径load_user_app()新增 eager ELF mapping 分支:读取全部 segment 数据后一次性映射用户页表,再uspace.write()。避免 lazy file-backed COW 路径lichee-fullbench-memfeature gate 排除 virtio/display/net 模块,与 userbench 一致
踩坑:lazy file-backed COW 导致 SIGILL
load_user_app() 走 lazy 路径时,第一次缺页由 handle_page_fault() 从 ramfs inode 读文件内容填页。D1 上 main 前触发 SIGILL,根因未定位到具体缺失的映射或权限位。绕过方案是 eager mapping 一次性填好所有页。
此问题不影响 async UART 验证——benchmark 通过 eager path 正常运行。
输出:
[starry-d1] fullbench memory-root start
[starry-d1] resolved /bin/benchmark -> load_user_app (eager)
... benchmark sections ...
Done.
benchmark exited with code: 0
[starry-d1] halting.
commit 587ec7c,分析文档 .claude/analysis/q19c-m1-memory-root-path-loader.md。
Q19C-M2:command-entry 模式(2026-07-11)¶
M1 通过 /bin/benchmark 文件名解析加载,M2 新增 command-entry 模式:内核直接调用 benchmark 入口,不经过 VFS 路径解析。
- 新增 Make 目标
lichee-memory-root-command,featurelichee-d1-fullbench-cmd kernel/src/entry.rs三路分发:smoke / userbench / fullbench-cmd(6998e09)- 完整 benchmark sections 输出,
benchmark exited with code: 0
归档为 openspec/changes/archive/2026-07-11-q19c-m2-m3-acceptance-alignment/。
Q19C-M3:rootfs-probe 删除(2026-07-11)¶
Q19C 原计划 M3 做 D1 SDMMC probe-only(d1_sdmmc_controller_base 识别 + block device 注册探测),真板日志只到 d1_sdmmc_controller_base=TBD,未输出 probe table。
方向更新后 M3 不再作为 UART gate:
- 删除
lichee-d1-rootfs-probefeature(kernel/Cargo.toml) - 删除对应 Makefile target 与
kernel/src/entry.rs分支 - 删除
kernel/src/lib.rs中 cfg 例外 - 旧方案归档到
openspec/changes/archive/2026-07-11-q19c-m3-polling-console-isolation/(未合入主 spec)
Q19C 收尾(2026-07-11)¶
D1 真板异步 UART 测试正式结束。收尾动作:
q19c-m2-m3-acceptance-alignment、q19c-lichee-full-starryos-benchmark、q19c-async-uart-closeout三个 change 归档- 证据表(M1 eager path、M2 command-entry)补入
openspec/specs/lichee-d1-fullbench/spec.md - Q19D SDMMC/rootfs 取消当前规划。若以后需要真实 storage/rootfs bring-up,重新 propose
归档入口:openspec/changes/archive/2026-07-11-ARC-202607111510/proposal.md。
Q19C-M1/M2/M3 产出位置¶
| 路径 | 用途 | 关键 commit |
|---|---|---|
kernel/src/entry.rs |
M1 path loader + M2 command-entry 分发 | 6998e09 |
kernel/src/mm/loader.rs |
eager ELF mapping 分支 | 587ec7c |
kernel/Cargo.toml |
lichee-d1-fullbench-mem / lichee-d1-fullbench-cmd feature |
6998e09 |
Makefile |
lichee-fullbench-mem / lichee-memory-root-command target |
6998e09 |
openspec/specs/lichee-d1-fullbench/spec.md |
M1/M2 证据表 | 6998e09 |
learned 条目(Q19C-M1/M2/M3 新增)¶
- L277:lazy file-backed COW → SIGILL on D1,eager ELF mapping 绕过(
587ec7c) - L278-L280:M1 memory-root path loader 完成(resolve + load_user_app eager)、M2 command-entry 完成(benchmark exit 0)、M3 rootfs-probe 删除(未合入主 spec)
当前状态¶
- Q19/Q19B/Q19C 已全部完成并归档。D1 真板异步 UART 测试正式结束。
- 活跃 OpenSpec change 仅剩
q17-smp-memory-ordering(18/19 tasks)。 - Q17 QEMU 修复完成,多 hart stress 待 Q20 VisionFive2 验证。
- Q19D SDMMC/rootfs 取消当前规划。
- Q20 VisionFive2 UART 验证等待硬件。
参考¶
- 前序:见
weekly-2026-W02 docs/licheerv-dock-bringup.md:流程笔记(2026-06-28 起持续更新)- Q19 归档:
openspec/changes/archive/2026-07-02-q19-lichee-d1-early-smoke/ - Q19B 归档:
openspec/changes/archive/2026-07-02-q19b-lichee-d1-benchmark/ - Q19C 收尾归档:
openspec/changes/archive/2026-07-11-ARC-202607111510/ - Q19C closeout:
openspec/changes/archive/2026-07-11-q19c-async-uart-closeout/ - Q19C M2/M3 对齐:
openspec/changes/archive/2026-07-11-q19c-m2-m3-acceptance-alignment/ - Q19C-M1 分析:
.claude/analysis/q19c-m1-memory-root-path-loader.md - Q19C-M2 分析:
.claude/analysis/q19c-m2-m3-shell-sdmmc-probe.md openspec/specs/learned/spec.mdL213-L280:踩坑与经验openspec/specs/architecture/spec.mdA040-A052:相关 ADR