From 61775e86e9d5f4c7a924c34600d3403b6fe9309b Mon Sep 17 00:00:00 2001 From: Microindole Date: Tue, 12 May 2026 16:53:33 +0800 Subject: [PATCH] docs(tasks): expand staged kernel roadmap --- docs/agents/tasks/01-early-debug.md | 38 +++++++ docs/agents/tasks/02-cpu-interrupts.md | 46 ++++++++ docs/agents/tasks/03-memory.md | 56 ++++++++++ docs/agents/tasks/04-time-scheduler.md | 130 +++++++++++++++++++++-- docs/agents/tasks/05-input-events.md | 60 +++++++++++ docs/agents/tasks/06-storage-vfs.md | 69 ++++++++++++ docs/agents/tasks/07-user-mode.md | 71 +++++++++++++ docs/agents/tasks/08-shell-tools.md | 69 ++++++++++++ docs/agents/tasks/09-driver-expansion.md | 73 +++++++++++++ docs/agents/tasks/10-real-machine.md | 60 +++++++++++ docs/agents/tasks/README.md | 4 +- 11 files changed, 663 insertions(+), 13 deletions(-) diff --git a/docs/agents/tasks/01-early-debug.md b/docs/agents/tasks/01-early-debug.md index 7af3f90..5030e6d 100644 --- a/docs/agents/tasks/01-early-debug.md +++ b/docs/agents/tasks/01-early-debug.md @@ -25,18 +25,53 @@ - 增加最小 `panic()`,panic 后停止 CPU。 - 为后续 printk、oops、内核符号和 crash dump 预留接口边界。 +### 1. Early console backend + +- 建立通用 early log 前端,后端可以是 QEMU debug port、COM1、framebuffer console 或后续平台 console。 +- x86 I/O port 访问集中在 arch 层,通用日志代码不能直接写端口。 +- early 阶段不能依赖动态内存、锁、线程或 VFS。 +- 后续切到正式 console 后,early backend 仍可作为 panic fallback。 + +### 2. Panic 与 halt 路径 + +- `panic()` 必须能在 allocator、scheduler、interrupt 都不可靠时输出最小信息。 +- panic 路径要尽量避免递归 panic,至少保证第二次进入时直接 halt。 +- arch 层提供 `arch_halt_forever()`,通用 panic 不直接写 `hlt` 循环细节。 +- 后续 oops 和 panic 要区分:可恢复异常进入 oops,不可恢复错误进入 panic。 + +### 3. Log buffer 与正式 printk 预留 + +- early log 前端后续应能迁移到 ring buffer,而不是让所有代码直接写串口。 +- 预留 log level、CPU id、timestamp、caller/source 信息。 +- 预留多 consumer:serial、debug port、framebuffer console、内存 buffer。 +- 预留 crash dump 或重启后读取日志的路径。 + +## Linux 参考原则 + +- 参考 Linux `printk`/console 分层:调用方写通用日志接口,console driver 负责具体输出设备。 +- 参考 Linux early console 思路:早期输出简单可靠,正式 console 接管后仍保留诊断价值。 +- 参考 Linux panic/oops 分离:panic 是不可恢复停机,oops 是异常诊断和策略入口。 +- 参考 Linux ring buffer 思路:日志先进入内核缓冲,再由不同 console 消费,避免业务代码绑定输出硬件。 + ## 非玩具化约束 - 日志前端不能直接绑定 COM1。 - COM1 端口号要集中定义,不能散落在业务代码。 - panic 路径不能依赖动态内存。 - 输出接口要允许后续接 framebuffer console。 +- 日志接口不能要求 scheduler、heap 或 interrupt 已经初始化。 +- panic/oops 策略不能写进异常入口汇编。 +- 正式 printk 出现后,early log 调用方不能被迫大规模改名或换接口。 +- 任何新增 backend 都不能影响其他 backend 的可用性。 ## 验收方式 - QEMU 日志中能看到 bootloader 和 kernel 输出。 - 串口或 debug log 中能看到 `boot services exited`。 - 人为触发 panic 时能看到 panic 信息并停止。 +- 禁用某一个输出 backend 时,其他 backend 仍可输出关键日志。 +- panic 路径在 heap 未初始化前也能输出。 +- `scripts/check.sh` 至少验证 debug log 和 serial log 两条路径。 ## 当前状态 @@ -55,6 +90,9 @@ - 内核符号化输出。 - framebuffer console。 - crash dump。 +- early log 到 printk 的接管流程。 +- panic 后保留最后日志的内存 buffer。 +- 多 CPU 后的日志串行化规则。 验收依据: diff --git a/docs/agents/tasks/02-cpu-interrupts.md b/docs/agents/tasks/02-cpu-interrupts.md index 288b19d..b8bd5ba 100644 --- a/docs/agents/tasks/02-cpu-interrupts.md +++ b/docs/agents/tasks/02-cpu-interrupts.md @@ -26,6 +26,41 @@ - 之后再接 PIC/APIC 和 IRQ。 - 异常路径输出异常栈、寄存器现场和符号化所需信息。 +### 1. CPU descriptor tables + +- GDT/TSS/IDT 初始化集中在 arch 层。 +- TSS 至少要为后续 IST、double fault 和用户态栈切换留位置。 +- IDT gate 属性必须集中设置,不能由每个 vector 零散指定。 +- 后续进入用户态前,要补 ring 3 相关段、syscall/sysret 或 int syscall 的入口边界。 + +### 2. Trap frame 与入口汇编 + +- 所有异常和 IRQ 入口都统一构造 `trap_frame`。 +- 汇编入口只负责保存现场、补齐 error code 形态、切换到 C handler。 +- C handler 不应依赖某个 vector 的临时栈布局。 +- trap frame 要保存后续诊断和用户态返回所需的寄存器、vector、error code、rip、rsp、rflags。 + +### 3. Exception policy + +- CPU exception 分发和 panic/oops 策略要分离。 +- page fault、invalid opcode、general protection、double fault 等常见异常要逐步拆出专门处理策略。 +- 当前 kernel-mode 未处理异常可以 panic;未来 user-mode 异常应终止进程而不是拖垮 kernel。 +- 异常日志要输出足够定位的信息,但不能把日志输出当成异常处理策略。 + +### 4. IRQ dispatch + +- 外部 IRQ vector 不能和 CPU exception vector 混用。 +- IRQ 分发应通过 handler 注册表,不把具体设备逻辑写进 trap dispatch。 +- EOI 时机必须清楚:已处理 IRQ 要发送,未识别 IRQ 的策略要单独记录。 +- 后续 APIC、IOAPIC、MSI/MSI-X 要能替换 PIC 路径,而不改通用 IRQ consumer。 + +## Linux 参考原则 + +- 参考 Linux arch entry 分层:入口汇编保存现场,通用 C 层做分发和策略。 +- 参考 Linux trap/irq 区分:exception 是 CPU 同步异常,IRQ 是外部异步事件,两者共享入口框架但语义分开。 +- 参考 Linux irqdomain/irqchip 思路:设备使用通用 IRQ 号和注册接口,硬件中断控制器细节留在 arch/driver 层。 +- 参考 Linux IST 使用方式:double fault、NMI 等高风险异常需要独立栈,不能依赖可能已经损坏的当前栈。 + ## 非玩具化约束 - 汇编入口只保存现场和跳转,不写策略。 @@ -33,12 +68,20 @@ - exception 和 IRQ 的入口可共享框架,但语义要区分。 - 不把中断处理写进 `kernel/main.c`。 - oops/panic 策略要和 trap 分发分离。 +- IRQ handler 注册、EOI 和调度请求不能互相混在一个设备专用路径里。 +- 用户态异常策略要提前预留,不能默认所有异常都 panic。 +- arch 层可以知道 vector 和 gate,通用层不应知道 IDT 编码细节。 +- double fault 等严重异常不能长期依赖普通内核栈。 ## 验收方式 - 主动触发 invalid opcode 或 divide error。 - 日志输出 vector、rip、rsp、error code。 - 未处理异常进入 panic。 +- 外部 IRQ vector 和 CPU exception vector 不冲突。 +- IRQ handler 可注册和分发,设备逻辑不在 trap dispatch 中硬编码。 +- page fault 路径能输出 fault address 和访问来源。 +- 后续用户态异常可以在不重写 trap frame 的前提下接入。 ## 当前状态 @@ -63,6 +106,9 @@ - 用户态异常返回。 - 可恢复异常处理。 - oops 格式和符号化输出。 +- syscall/sysret 或 int syscall 入口。 +- nested interrupt 和 preempt/reschedule 边界。 +- NMI、spurious IRQ 和未知 vector 策略。 验收依据: diff --git a/docs/agents/tasks/03-memory.md b/docs/agents/tasks/03-memory.md index 631ee44..3c70e73 100644 --- a/docs/agents/tasks/03-memory.md +++ b/docs/agents/tasks/03-memory.md @@ -28,6 +28,48 @@ - 建立最小内核堆。 - 为后续匿名页、缺页加载、COW、`mmap`、page cache、换页预留接口。 +### 1. Memory map 与长期区域模型 + +- boot memory map 只作为启动输入,不能直接成为长期内核内存类型。 +- 建立内核自己的 memory region 类型:usable、reserved、kernel image、boot data、MMIO、ACPI reclaim 等。 +- 记录物理地址范围、页对齐、可分配性和后续热插拔/NUMA 预留信息。 +- 不写死物理内存大小、页数量或固件返回顺序。 + +### 2. Physical page allocator + +- 当前可以先用 free list,但接口要允许替换为 buddy allocator。 +- 每个物理页后续要有 page metadata,记录引用计数、状态、所属用途和链表节点。 +- allocator 需要能区分单页、小批量页和连续页需求。 +- 后续 DMA、page cache、匿名页、COW、swap 都要能复用同一 page model。 + +### 3. Virtual memory 与 page table + +- arch 页表代码负责页表格式、flag 编码、TLB 操作和地址空间切换。 +- 通用 MM 层负责虚拟地址区域、映射策略和对象生命周期。 +- 内核地址空间布局必须文档化,用户地址空间和内核地址空间要有硬边界。 +- page fault handler 要区分诊断、按需分配、权限错误和用户态进程终止。 + +### 4. Kernel heap 与小对象分配 + +- 当前 `kmalloc()` 可以简单,但不能让调用方依赖永不失败或永不释放。 +- 小对象分配后续应演进到 slab/slub 或等价缓存分配器。 +- heap 元数据不能和 x86 页表实现强耦合。 +- 释放路径要能检测基础错误,例如 double free 或明显越界的后续调试接口。 + +### 5. Future VM capabilities + +- 为匿名页、文件页、page cache、COW、`mmap`、换页和内存回收预留结构边界。 +- VFS/page cache 不能绕过 MM 直接私有管理所有缓存页。 +- 用户态出现前可以先只做 kernel mapping,但接口不能排斥多地址空间。 +- 后续进程退出必须能回收地址空间、页表页、匿名页和文件映射引用。 + +## Linux 参考原则 + +- 参考 Linux buddy + slab/slub 分层:页级分配和小对象分配分开演进。 +- 参考 Linux `struct page` 思路:物理页要有长期 metadata,而不是只有 free list 节点。 +- 参考 Linux VMA/page fault 思路:缺页不是单纯 panic,未来要能按区域策略处理。 +- 参考 Linux page cache 思路:文件缓存属于 MM/VFS 共同边界,不能被具体文件系统或块驱动私有化。 + ## 非玩具化约束 - 不写死物理内存大小。 @@ -37,6 +79,10 @@ - 地址空间布局要文档化。 - 用户地址空间和内核地址空间的边界不能依赖调用方自觉遵守。 - 不能把 page cache 和匿名页排除在长期模型之外。 +- 页表实现不能混入启动 selftest 或具体业务逻辑。 +- 通用 MM 接口不能暴露 x86 页表 flag 编码。 +- page fault 诊断和 page fault 策略要分离。 +- 内核堆失败路径必须被调用方看见,不能默认分配永远成功。 ## 验收方式 @@ -45,6 +91,10 @@ - page fault 能输出有效诊断。 - 内核堆能分配小对象。 - 后续能在此基础上加入 COW、`mmap`、换页和内存回收。 +- 页表 selftest 不和页表主实现混在同一文件职责内。 +- `kmalloc()`/`kfree()` 有基础复用验证。 +- page fault 测试能区分 not-present、权限和访问类型。 +- 后续添加用户地址空间时不需要重写物理页 allocator。 ## 当前状态 @@ -70,6 +120,12 @@ - page metadata。 - buddy allocator。 - slab/slub 或等价小对象缓存。 +- VMA 或等价虚拟区域管理。 +- 用户地址空间创建、复制和销毁。 +- COW、匿名页和文件页。 +- page cache、writeback 和内存回收。 +- swap 或等价换页机制。 +- DMA 可用内存和 MMIO 映射边界。 验收依据: diff --git a/docs/agents/tasks/04-time-scheduler.md b/docs/agents/tasks/04-time-scheduler.md index 6a4fa20..0b093de 100644 --- a/docs/agents/tasks/04-time-scheduler.md +++ b/docs/agents/tasks/04-time-scheduler.md @@ -23,13 +23,80 @@ ## 实现内容 -- 建立 kernel thread。 -- 建立上下文切换。 -- 建立 run queue。 -- 建立 sleep/wakeup。 -- 建立基础 spinlock 或 interrupt-safe lock。 -- 接入 timer tick 或 one-shot timer。 -- 为 workqueue、deferred work、completion、引用计数生命周期管理预留位置。 +### 1. Timer 与时钟基础 + +- 接入一个可替换的硬件 timer 后端,当前可以先用 PIT periodic timer。 +- 通用层只暴露 `timer_tick()`、`timer_ticks()` 和后续 timeout/timer callback 所需接口。 +- 调度器不能直接读取 PIT/APIC 硬件细节,只能依赖通用 time/timer 层。 +- tick handler 中只做短路径工作:更新时间、唤醒到期 sleep、标记 reschedule,不在 IRQ handler 内做复杂策略。 +- 后续预留 one-shot timer、高精度 timer 和 timer wheel/min-heap 等实现空间。 + +### 2. Kernel thread 与上下文切换 + +- 建立 kernel thread 对象,包含 id、状态、入口、参数、内核栈、调度链表节点和等待链表节点。 +- 建立新线程 trampoline,让线程从独立内核栈进入入口函数。 +- 建立 arch 私有上下文切换入口,只保存/恢复该 ABI 需要的调度上下文。 +- 线程入口返回不能落入未知地址,必须统一进入 thread exit 路径。 +- 线程对象和内核栈不能依赖“永不释放”,必须有明确生命周期和回收规则。 + +### 3. Run queue 与调度核心 + +- 建立动态 run queue,线程数量不能固定写死。 +- 先实现单 CPU round-robin,再为优先级、时间片、per-cpu run queue 留边界。 +- 调度核心需要集中处理 `RUNNING`、`READY`、`SLEEPING`、`WAITING`、`DEAD` 等状态转换。 +- 调度选择、入队、出队和当前线程切换必须有统一锁规则。 +- idle thread 必须作为没有 runnable thread 时的兜底执行体。 + +### 4. Interrupt-exit reschedule + +- timer IRQ 只设置 `need_resched`,真正切换应收敛在明确的 IRQ 返回边界。 +- `sched_irq_exit()` 要逐步演进为 trap-frame aware 模型,明确从中断返回时哪些现场可以被切换。 +- 不要长期把普通协作式 `sched_yield()` 栈切换入口当成完整抢占式切换模型。 +- 后续进入用户态后,用户态返回边界、内核可抢占点和 syscall 返回边界要能共享这套设计。 +- 任意 IRQ handler 都不应该直接调用会睡眠的接口。 + +### 5. Sleep、wait queue 与 lost wakeup + +- `sched_sleep()` 负责按 tick 睡眠并由 timer 唤醒。 +- wait queue 要提供基础 sleep/wakeup、条件等待和带 timeout 的条件等待。 +- 条件检查、入队睡眠和 wakeup 必须有明确锁规则,避免 lost wakeup。 +- wakeup 必须发生在修改条件之后;等待方必须在同一同步规则下检查条件并决定是否睡眠。 +- wait queue API 要区分可睡眠路径和不可睡眠路径,不能允许 IRQ handler 进入睡眠。 +- timeout wait 被 timer 唤醒后,必须能从 wait queue 清理残留节点。 + +### 6. Locking 与不可睡眠上下文 + +- 建立单 CPU interrupt-safe lock:保存中断状态、关闭中断、释放时恢复原状态。 +- 明确哪些锁可以在 IRQ 入口使用,哪些路径允许睡眠,哪些路径必须原子完成。 +- run queue、wait queue、timer sleep list、thread id 分配等共享状态必须逐步纳入锁保护。 +- 禁止持有不可睡眠锁时调用 `sched_yield()`、`sched_sleep()` 或 wait queue sleep。 +- 后续 SMP 前,需要先把接口命名和调用约束整理清楚,避免把单 CPU 假设泄漏到所有调用方。 + +### 7. Thread lifecycle 与回收 + +- 线程入口返回后进入统一退出路径,而不是直接释放自身栈。 +- 区分当前线程不能立即释放自身内核栈的问题,调度器只能在安全边界回收非当前 DEAD 线程。 +- 为未来 `join/wait`、进程退出、引用计数和资源释放预留 `ZOMBIE` 或等价状态。 +- 线程释放必须覆盖线程对象、内核栈、等待队列残留、run queue 残留和调试信息。 +- 回收路径需要自测,避免重复释放、释放当前线程栈或释放仍在队列中的线程。 + +### 8. Deferred work、completion 与后续驱动基础 + +- 为 workqueue/deferred work 预留接口位置,让 IRQ handler 可以把复杂工作推迟到线程上下文。 +- 为 completion 或一次性事件等待预留基础,后续驱动初始化和 I/O 完成会使用。 +- 为 timer callback 或 delayed work 预留设计,避免所有超时逻辑都手写在调度器里。 +- 这些能力可以晚于基础 wait queue 实现,但任务文档必须提前记录边界,避免后续驱动直接依赖临时接口。 + +## Linux 参考原则 + +本阶段不照搬 Linux CFS、SMP、RCU、hrtimer 等完整复杂度,但接口边界应参考 Linux 的长期分层方式: + +- `kernel/sched/` 风格:调度策略、线程状态和 run queue 维护集中在调度子系统,不散落到驱动或 `kernel/main.c`。 +- `wait_event*` 风格:等待方围绕“条件检查 + 入队睡眠 + 被唤醒后重新检查条件”组织逻辑,条件本身由调用方拥有。 +- `wake_up*` 风格:唤醒方先改变受保护条件,再唤醒等待队列;否则容易出现 lost wakeup。 +- `spin_lock_irqsave()` 风格:在中断和普通内核路径共享的数据结构上,先用保存/关闭中断的单 CPU lock 建立正确语义。 +- `kthread` 风格:线程函数返回、显式退出、停止请求和资源回收要有统一生命周期,不依赖“这个线程永远不结束”。 +- `timer/workqueue` 风格:IRQ handler 做最少工作,复杂处理推迟到线程上下文或 deferred work。 ## 非玩具化约束 @@ -39,6 +106,12 @@ - 日志只能辅助观察,不能成为调度逻辑的一部分。 - 内核对象不能依赖“永不释放”的假设。 - 任何可睡眠路径和不可睡眠路径要从接口上区分。 +- 任何会修改 run queue、wait queue、sleep list 或 thread state 的路径都要说明锁规则。 +- wait queue 条件等待必须能解释为什么不会丢唤醒。 +- IRQ handler 不能直接执行可能睡眠或长时间运行的工作。 +- 线程状态转换必须单向、可审计,不能通过随意改 `state` 修补行为。 +- 当前阶段可以只支持单 CPU,但接口不能把“永远单 CPU”写死成公共契约。 +- arch 层只负责 trap、IRQ、timer 硬件和上下文切换细节,不承载通用调度策略。 ## 验收方式 @@ -46,6 +119,12 @@ - 线程可以 sleep 并被 timer 唤醒。 - 调度现场保存和恢复稳定。 - 基础对象生命周期规则有文档和调用约束。 +- wait queue 能完成普通 wakeup、条件等待和 timeout 等待。 +- timeout 路径不会把线程永久留在 wait queue 中。 +- timer IRQ 触发后,调度请求在明确的 IRQ exit 边界被消费。 +- 线程入口正常返回后进入统一退出和回收路径。 +- `scripts/check.sh` 覆盖 timer、thread、sleep、wait queue、timeout wait 和退出回收的可观测日志。 +- 新增调度 API 必须同时更新公开头文件、自测和任务文档。 ## 当前状态 @@ -77,11 +156,40 @@ 后续扩展: -- 把当前 `sched_irq_exit()` 继续收敛为更严格的 trap-frame aware interrupt-exit reschedule 模型,避免把普通线程栈切换入口长期当成完整抢占式切换。 -- 继续扩大 interrupt-safe lock 覆盖范围,明确可睡眠路径和不可睡眠路径的锁规则。 -- 为 wait queue 增加更严格的状态检查,并把条件检查与 wakeup 边界纳入明确锁规则。 +### A. 调度状态机收紧 + +- 明确合法状态转换,例如 `READY -> RUNNING -> READY`、`RUNNING -> SLEEPING/WAITING`、`SLEEPING/WAITING -> READY`、`RUNNING -> DEAD`。 +- 增加状态转换辅助函数,减少外部代码直接写 `thread->state`。 +- 自测非法状态转换和重复入队问题。 + +### B. wait queue 锁语义 + +- 为 wait queue 增加内部锁或要求调用方持有指定锁,并在接口命名中体现约束。 +- 把条件检查、等待入队和睡眠切换收敛成一个不会丢唤醒的模式。 +- 区分 `wake_one`、`wake_all`、timeout wakeup 和条件 wakeup 的状态处理。 +- 检查 wakeup 是否可能唤醒 DEAD、RUNNING 或未入队线程。 + +### C. interrupt-exit reschedule + +- 把当前 `sched_irq_exit()` 继续收敛为更严格的 trap-frame aware interrupt-exit reschedule 模型。 +- 明确 interrupt nested、idle、当前线程不可抢占等情况下是否允许调度。 +- 避免把普通线程栈切换入口长期当成完整抢占式切换。 +- 为未来 syscall return 和 user-mode return 复用同一 reschedule 边界。 + +### D. thread lifecycle + - 为线程退出增加更完整的生命周期状态、引用规则和最终释放约束。 +- 补充“当前线程不能释放自身内核栈”的文档和自测。 +- 为未来 `kthread_stop()`、join/wait 和进程退出保留接口空间。 +- 回收路径需要覆盖等待队列残留、run queue 残留和 timer sleep 残留。 + +### E. deferred execution + +- 增加最小 workqueue 或 deferred work,让 IRQ handler 可以只入队工作并唤醒 worker。 +- 增加 completion 风格的一次性等待原语,供驱动初始化和异步完成使用。 +- 增加 delayed work 或 timer callback 的设计草案,避免 timeout 逻辑复制到每个子系统。 下一阶段: -- 继续在 `04-time-scheduler.md` 内推进 interrupt-safe lock、线程退出回收和更严格的 interrupt-exit reschedule。 +- 继续在 `04-time-scheduler.md` 内推进 wait queue 锁语义、线程生命周期和更严格的 interrupt-exit reschedule。 +- 在这些边界稳定前,不急着进入 `05-input-events.md` 的键盘驱动实现。 diff --git a/docs/agents/tasks/05-input-events.md b/docs/agents/tasks/05-input-events.md index 86606d1..41ce8e0 100644 --- a/docs/agents/tasks/05-input-events.md +++ b/docs/agents/tasks/05-input-events.md @@ -24,16 +24,76 @@ - 建立输入事件队列。 - 为终端输入提供读取接口。 +### 1. Input core + +- 建立通用 input device 和 input event 结构,键盘只是 input device 的一种。 +- input core 负责设备注册、事件入队、事件读取和等待队列唤醒。 +- event 结构要能表达 key press/release、key code、modifier、设备来源和时间戳。 +- 事件队列要有容量、溢出策略和统计信息,不能无限增长。 + +### 2. Keyboard driver + +- PS/2 keyboard driver 只负责读取 scancode、维护按键状态、转换为通用 key event。 +- scancode set、keyboard layout 和 keymap 要分层,不能把美式键盘布局写死到驱动主路径。 +- modifier、repeat、release event、extended scancode 要逐步补齐。 +- 键盘驱动不直接写 terminal、shell 或 VFS。 + +### 3. IRQ 与 deferred processing + +- keyboard IRQ handler 只做短路径:读取数据、确认硬件状态、入队原始或半处理事件。 +- 复杂解码、repeat 和 terminal line discipline 可以推迟到线程上下文。 +- IRQ handler 不能 sleep,不能直接等待队列条件,不能调用 shell。 +- 如果需要较复杂处理,先建立 deferred work 或 input worker。 + +### 4. Terminal input boundary + +- terminal/tty 层从 input core 读取 key event,再处理行编辑、回显、控制字符和后续 job control。 +- shell 只读取 terminal 字节流或行,不直接读取 keyboard scancode。 +- 后续 USB HID、图形终端或串口终端应复用同一 terminal/input 边界。 +- 输入路径要保留 blocking read、nonblocking read 和 poll/select 的接口位置。 + +## Linux 参考原则 + +- 参考 Linux input subsystem:设备驱动上报通用 input event,上层消费者不绑定具体硬件。 +- 参考 Linux serio/i8042/atkbd 分层:控制器、键盘协议和 input 事件上报分开。 +- 参考 Linux tty/line discipline 思路:键盘事件到 shell 输入之间应有 terminal 层,不让 shell 直接处理硬件事件。 +- 参考 Linux IRQ bottom half/workqueue 思路:中断路径短,复杂处理推迟。 + ## 非玩具化约束 - 键盘驱动只产生事件,不直接操作 shell。 - 键盘布局要可替换。 - 输入队列接口要允许未来接 USB HID。 - 中断 handler 中不要做复杂处理。 +- input core 不依赖 PS/2,PS/2 driver 不依赖 terminal。 +- event queue 要有锁和等待语义,不能靠忙等读取。 +- 事件丢失、队列满和未知 scancode 必须可观测。 +- blocking read 必须通过 wait queue 或等价机制睡眠,不能轮询。 +- terminal 控制字符和 shell 命令解析不能写进 keyboard driver。 ## 验收方式 - 按键触发中断。 - kernel 能读取 key event。 - 后续 shell 可复用同一输入接口。 +- press/release event 可区分。 +- unknown scancode 不会破坏输入队列。 +- 没有输入时读取方会睡眠,有输入时被唤醒。 +- keyboard selftest 或 QEMU 输入测试能验证事件路径。 +- 后续接入 shell 时不需要修改 keyboard driver 主逻辑。 +## 当前状态 + +未开始。 + +进入本阶段前,`04-time-scheduler.md` 至少应具备可靠 wait queue 和明确的可睡眠/不可睡眠上下文规则。 + +## 后续扩展 + +- USB HID keyboard。 +- 鼠标和相对/绝对坐标事件。 +- key repeat。 +- 多 keyboard 设备。 +- terminal line discipline。 +- nonblocking input、poll/select。 +- session、foreground process group 和 job control。 diff --git a/docs/agents/tasks/06-storage-vfs.md b/docs/agents/tasks/06-storage-vfs.md index 1b9581c..411014f 100644 --- a/docs/agents/tasks/06-storage-vfs.md +++ b/docs/agents/tasks/06-storage-vfs.md @@ -27,6 +27,48 @@ - 后续再加入 write 和持久化文件系统。 - 为 page cache、block cache、writeback 和崩溃一致性预留边界。 +### 1. Block layer 与数据来源 + +- 初期可以使用 initramfs/ramdisk,让 VFS 在没有真实磁盘驱动时先闭环。 +- block device 接口要表达设备大小、块大小、read/write 请求和完成状态。 +- 块设备驱动不直接解析文件系统,也不直接服务 shell。 +- 后续 virtio-blk、AHCI、NVMe 应通过同一 block device 接口接入。 + +### 2. VFS object model + +- 建立 superblock、inode、dentry、file 或等价对象边界。 +- inode 表示文件对象和元数据,dentry 表示路径缓存,file 表示一次打开实例和 offset。 +- 对象生命周期要有引用计数或明确所有权。 +- VFS 调用方不能直接依赖某个具体文件系统结构。 + +### 3. Path lookup + +- 路径解析要支持绝对路径、相对路径、`.`、`..` 和目录边界。 +- lookup 需要区分不存在、不是目录、权限不足和 I/O 错误。 +- 当前可以先不实现 mount namespace,但接口要为 mount point 和根目录切换留位置。 +- 路径字符串来自用户态时,必须经过用户指针复制和长度检查。 + +### 4. File operations + +- 先实现 `open/read/close/readdir`,再加入 `write/create/unlink/rename`。 +- file operation 通过表或函数指针分发,VFS 不写死 ramfs/initramfs。 +- 目录读取要有稳定迭代语义,不能只打印日志。 +- offset、EOF、短读和错误码要从一开始定义清楚。 + +### 5. Cache 与一致性预留 + +- page cache/block cache 不应属于某个具体磁盘驱动。 +- 只读阶段可以不做 writeback,但接口要保留 dirty、flush、invalidate。 +- 后续可写文件系统需要定义崩溃一致性策略,例如 journal、copy-on-write 或简单同步写。 +- VFS、MM 和 block layer 的缓存边界要清楚,避免同一数据被多套缓存重复管理。 + +## Linux 参考原则 + +- 参考 Linux VFS:上层通过通用 inode/file/dentry/superblock 语义访问不同文件系统。 +- 参考 Linux block layer:文件系统发出块请求,具体设备驱动处理硬件细节。 +- 参考 Linux page cache:文件数据缓存属于 MM/VFS 共同边界,而不是具体文件系统私有数组。 +- 参考 Linux file operations:具体文件系统实现操作表,VFS 负责统一分发和生命周期。 + ## 非玩具化约束 - VFS 不依赖某个具体文件系统。 @@ -35,6 +77,11 @@ - 缓存层不能和具体磁盘驱动耦合。 - VFS 对象生命周期必须明确,不能靠全局静态对象规避释放问题。 - 文件权限、时间戳、inode 编号等 POSIX 语义要保留位置。 +- open file 和 inode 不能混成同一个对象。 +- VFS 错误要能映射到后续用户态 errno。 +- read/write 不能只服务 demo 文件,必须处理 offset、EOF 和短读。 +- 文件系统 selftest 不能依赖 shell 已经存在。 +- 后续可写路径不能要求重写只读 VFS API。 ## 验收方式 @@ -42,3 +89,25 @@ - 可列出目录。 - 替换具体 FS 不影响 VFS 调用方。 - 后续能加入可写缓存和 writeback,而不重写 VFS 调用层。 +- initramfs/ramfs 和至少一个 VFS selftest 通过同一 open/read/readdir 接口。 +- 路径解析错误有明确返回值。 +- file offset 行为可测试。 +- 多次 open 同一文件能得到独立 file object。 +- 后续用户态 `cat/ls` 可以直接复用当前 VFS 接口。 + +## 当前状态 + +未开始。 + +进入本阶段前,`03-memory.md` 应至少有稳定 heap,`04-time-scheduler.md` 应具备锁和等待基础。 + +## 后续扩展 + +- page cache。 +- block cache。 +- writeback。 +- 可写 ramfs。 +- FAT/ext2 等简单持久化文件系统。 +- mount table。 +- 权限、时间戳和 inode 编号。 +- 设备文件、pipe 和 socket 文件接口。 diff --git a/docs/agents/tasks/07-user-mode.md b/docs/agents/tasks/07-user-mode.md index b3796c7..dc3c41c 100644 --- a/docs/agents/tasks/07-user-mode.md +++ b/docs/agents/tasks/07-user-mode.md @@ -28,6 +28,49 @@ - 为 POSIX syscall、`fcntl/stat/chmod`、signal、pipe、socket、eventfd、futex、共享内存、poll/select 和 IPC 预留 ABI 边界。 - 为 uid/gid、用户/组、文件权限、进程权限、capability 或等价隔离模型预留进程凭据结构。 +### 1. User address space + +- 每个进程需要独立地址空间,内核映射和用户映射边界清楚。 +- 用户页权限必须区分 user/supervisor、read/write、execute。 +- 进程退出时必须释放用户页、页表页、VFS 引用和其他资源。 +- 后续 `fork`、COW、`mmap` 和 shared memory 要能接入同一地址空间模型。 + +### 2. Syscall ABI + +- 定义 syscall number、参数寄存器、返回值、错误码和 clobber 规则。 +- syscall 表要稳定记录,不能由 demo 程序和 kernel 临时约定。 +- syscall handler 必须复制和检查用户指针,不能直接解引用用户地址。 +- syscall 返回边界要能和调度、signal、进程退出共享。 + +### 3. Process/thread model + +- 区分进程、线程、地址空间、内核调度线程和打开文件表。 +- 早期可以一个进程一个线程,但结构不能排斥多线程。 +- 建立 pid、父子关系、退出码、wait 状态和 zombie 回收。 +- 后续 `fork/exec/wait`、线程、signal 和 job control 要有可扩展空间。 + +### 4. ELF loader + +- ELF loader 只负责校验和映射 ELF,不负责文件系统路径策略。 +- 检查 ELF header、program header、segment 权限、对齐、入口地址和用户地址范围。 +- 加载器要建立用户栈、argc/argv/envp 或最小等价启动约定。 +- 非法 ELF 必须返回错误,不能 panic。 + +### 5. Fault and signal boundary + +- 用户态 page fault、invalid opcode、general protection 等异常应终止当前进程或转成后续 signal。 +- kernel fault 和 user fault 策略必须分开。 +- 预留 signal、kill、wait status 和 core dump/debug 信息。 +- 用户态崩溃不能破坏内核调度器、VFS 或其他进程。 + +## Linux 参考原则 + +- 参考 Linux task/mm/files 分离:调度实体、地址空间和文件表不是同一个对象。 +- 参考 Linux syscall ABI:syscall number 和参数规则稳定,libc 可以独立绑定。 +- 参考 Linux ELF loader:VFS 提供文件,loader 校验 program header 并建立用户映射。 +- 参考 Linux user access helpers:所有用户指针都要复制/检查,不能直接信任。 +- 参考 Linux wait/exit/zombie 模型:进程退出和资源释放分阶段完成。 + ## 非玩具化约束 - syscall 表要稳定记录。 @@ -37,6 +80,11 @@ - syscall 不能只按当前 demo 程序硬编码。 - 进程资源释放必须有明确所有权和引用计数规则。 - `fork/exec/wait`、signal、pipe、poll/select 是运行复杂 Unix 程序的关键路径,不能被路线遗漏。 +- 用户态入口和 syscall 返回必须经过明确的 arch 边界。 +- ELF loader 不能把文件系统、权限和地址空间策略混在一个函数里。 +- 用户栈布局要文档化,不能靠某个 demo 程序猜测。 +- errno/错误码语义要能被 libc 映射。 +- 进程退出不能泄漏页表、VFS file、cwd、argv/envp 或 wait 状态。 ## 验收方式 @@ -44,3 +92,26 @@ - kernel 能回收用户进程资源。 - 非法用户访问能进入异常处理并终止进程。 - syscall ABI 文档化,后续可以被 libc 绑定。 +- 非法 syscall number 返回明确错误。 +- 用户指针越界不会导致 kernel panic。 +- ELF 错误输入有测试,返回加载失败。 +- 父进程能 wait 到子进程退出码。 +- 用户态进程反复启动和退出后,内存和 file 引用不会持续增长。 + +## 当前状态 + +未开始。 + +进入本阶段前,`03-memory.md` 需要支持用户地址空间基础,`06-storage-vfs.md` 需要能读取 ELF 或 init 程序。 + +## 后续扩展 + +- `fork/exec/wait`。 +- signal。 +- pipe。 +- shared memory。 +- futex。 +- poll/select。 +- uid/gid、权限和 capability。 +- 动态链接。 +- ptrace 或基础调试接口。 diff --git a/docs/agents/tasks/08-shell-tools.md b/docs/agents/tasks/08-shell-tools.md index e6a6d3a..a82a533 100644 --- a/docs/agents/tasks/08-shell-tools.md +++ b/docs/agents/tasks/08-shell-tools.md @@ -27,6 +27,48 @@ - 为 tty、session、job control 留出后续位置。 - 为 procfs/sysfs/debugfs、ftrace、perf、crash dump 类可观测接口预留路径。 +### 1. init process + +- `init` 是第一个用户态进程,负责启动 shell 和回收孤儿进程。 +- kernel 只启动 init,不直接启动 shell 或具体命令。 +- init 失败要有可观测错误和 fallback 策略。 +- 后续 service manager 可以替换 init,但不影响 kernel 进程模型。 + +### 2. Shell and command execution + +- shell 运行在用户态,通过 syscall、VFS 和 terminal 访问系统能力。 +- shell 负责解析命令行、查找可执行文件、spawn/exec、wait 和显示退出状态。 +- 内建命令和外部命令要区分,不能把所有工具写进 shell。 +- shell 不能调用 kernel 内部符号或绕过 VFS。 + +### 3. Minimal libc and user ABI + +- 建立最小 libc 封装 syscall、errno、字符串、内存、路径和文件 API。 +- 用户程序通过 libc 或稳定 syscall ABI 访问 kernel,不包含 kernel 私有头文件。 +- `argv/envp`、工作目录、文件描述符和退出码语义要逐步稳定。 +- 后续移植更复杂工具时,优先补 libc/VFS/syscall 缺口,而不是给工具写特殊路径。 + +### 4. Observability interfaces + +- kernel 状态通过 syscall 或虚拟文件系统暴露,例如 procfs/debugfs 的早期等价物。 +- 调试命令读取这些接口,不直接链接 kernel 数据结构。 +- 先提供进程列表、内存统计、mount/file 状态、timer/scheduler 简要状态。 +- 后续 ftrace、perf、crash dump 和符号化输出放在可观测接口路线中。 + +### 5. Terminal and job control + +- shell 从 terminal/tty 读取输入,不直接读取 keyboard event。 +- 预留 session、controlling terminal、foreground process group 和 signal 交互。 +- 早期可以没有完整 job control,但接口不能排斥 Ctrl-C、后台任务和管道。 +- terminal 行编辑、回显和控制字符不写进 keyboard driver。 + +## Linux 参考原则 + +- 参考 Linux init 模型:kernel 启动第一个用户进程,系统策略留给用户态。 +- 参考 Unix shell 模型:shell 通过 fork/exec/wait 或等价接口组合程序。 +- 参考 Linux procfs/sysfs/debugfs:调试信息通过文件或稳定接口暴露,而不是用户程序读 kernel 内存。 +- 参考 Linux tty/session/job control:交互输入输出是 terminal 层职责,不属于键盘驱动或 shell 内核特权。 + ## 非玩具化约束 - shell 必须运行在用户态。 @@ -35,6 +77,11 @@ - 工具能力应服务于后续 git 移植。 - shell 不是内核调试器,不能用 shell 规避系统调用和 VFS 的缺失。 - `git` 目标至少需要可用 libc、文件状态、权限、时间、路径、进程等待等接口。 +- init、shell、基础命令不能混成一个二进制除非接口仍保持独立。 +- 外部命令必须走进程创建和 VFS 加载路径。 +- 用户态工具不能包含 kernel 私有结构体布局。 +- 调试接口要只读优先,避免早期工具直接修改 kernel 状态。 +- 缺失能力应补 syscall/libc/VFS,而不是给单个命令加后门。 ## 验收方式 @@ -43,3 +90,25 @@ - shell 能执行至少两个外部命令。 - 命令可访问 VFS。 - 基础用户空间接口能支撑后续移植更复杂工具。 +- init 能启动 shell 并回收退出的子进程。 +- `ls` 通过 VFS readdir 工作,`cat` 通过 open/read 工作。 +- shell 能显示外部命令退出状态。 +- 调试命令通过虚拟文件或 syscall 读取状态。 +- 用户态程序不直接包含 kernel 私有头。 + +## 当前状态 + +未开始。 + +进入本阶段前,需要 `05-input-events.md`、`06-storage-vfs.md` 和 `07-user-mode.md` 的最小闭环。 + +## 后续扩展 + +- 管道和重定向。 +- 环境变量。 +- cwd 和相对路径。 +- job control。 +- procfs/sysfs/debugfs。 +- 更完整 libc。 +- 动态链接。 +- git 移植所需的文件、时间、权限和进程接口。 diff --git a/docs/agents/tasks/09-driver-expansion.md b/docs/agents/tasks/09-driver-expansion.md index 9aedc17..a572c9a 100644 --- a/docs/agents/tasks/09-driver-expansion.md +++ b/docs/agents/tasks/09-driver-expansion.md @@ -35,6 +35,50 @@ - 后续再做网络和音频。 - 规划 socket API 和网络栈接入点,但本地 git 阶段不要求网络。 +### 1. Device model + +- 建立 device、driver、bus、resource 的通用对象模型。 +- 设备发现、驱动匹配、probe/remove 和资源释放要分层。 +- 驱动不能私自扫描所有硬件或直接改其他子系统内部结构。 +- 设备生命周期要有引用和状态,支持 probe 失败后的清理。 + +### 2. Platform discovery + +- ACPI 负责 x86 UEFI/PC 平台的硬件描述、IRQ routing、电源和拓扑信息。 +- Device Tree 作为后续非 ACPI 平台入口,不和 ACPI 逻辑混写。 +- 平台层解析表,通用驱动层只消费抽象 device/resource。 +- 平台信息错误或缺失时要有诊断日志,不能静默使用危险默认值。 + +### 3. Bus and resource management + +- PCI 枚举要生成通用 device,并记录 BAR、IRQ、DMA mask、vendor/device id。 +- MMIO、PIO、IRQ、DMA resource 由统一 resource allocator 管理。 +- 驱动 probe 前申请资源,remove 或失败时释放资源。 +- 后续 USB、virtio、platform device 应能复用 bus/device/driver 模型。 + +### 4. Interrupt and timer controllers + +- PIC 可以作为早期路径,后续 APIC/IOAPIC/MSI/MSI-X 要接入统一 IRQ 层。 +- IRQ routing 由平台和中断控制器驱动处理,设备驱动不直接写硬编码 vector。 +- HPET/APIC timer 可作为 PIT 的后续替代,不改变通用 timer API。 +- spurious IRQ、共享 IRQ 和中断屏蔽策略要有文档。 + +### 5. Storage, network, graphics and sound + +- 存储优先级高于网络和音频,因为 VFS、用户态和工具链依赖它。 +- virtio-blk 是 QEMU 友好的早期目标,AHCI/NVMe 是真机存储目标。 +- framebuffer console 可改善真机诊断,但不能替代 serial/early log。 +- 网络栈和 socket API 需要单独路线,本地 git 目标不要求联网。 +- 音频是后期设备,不应阻塞内核主线。 + +## Linux 参考原则 + +- 参考 Linux device model:device/driver/bus/resource 分层,probe/remove 管理生命周期。 +- 参考 Linux PCI/ACPI 分层:平台发现和具体驱动分开,驱动通过抽象资源访问硬件。 +- 参考 Linux irqchip/irqdomain 思路:设备驱动不直接管理 CPU vector。 +- 参考 Linux DMA mapping 思路:DMA 地址能力和缓存一致性不能被驱动随意假设。 +- 参考 Linux driver core:新驱动应插入框架,不要求修改 VFS、shell、调度器等无关层。 + ## 非玩具化约束 - 设备发现、驱动 probe、资源分配要分层。 @@ -43,6 +87,11 @@ - 新驱动不能要求修改 shell、VFS、调度器等无关层。 - 硬件发现、资源分配和驱动绑定必须从设备模型进入,不能由单个驱动私自扫描全部硬件。 - ACPI/PCI/Device Tree 类平台信息要隔离在平台层,不能泄漏到通用子系统。 +- probe 失败必须释放已申请资源。 +- 驱动不能长期 busy wait,应使用 IRQ、wait queue 或 deferred work。 +- DMA 不能假设所有物理内存都可寻址或缓存一致。 +- 平台设备不能把某台机器的 ACPI 表布局写死进通用代码。 +- QEMU 专用设备支持不能破坏真机路径。 ## 验收方式 @@ -50,3 +99,27 @@ - 至少一种块设备可接入 VFS。 - 新驱动加入时只影响对应驱动和通用驱动框架。 - 后续可接入网络、USB、音频,而不重写已有核心子系统。 +- PCI 枚举能列出 vendor/device id 和 BAR resource。 +- 一个驱动 probe 失败路径能被测试或人工触发并正确清理。 +- IRQ routing 不要求设备驱动硬编码 vector。 +- virtio-blk 或等价块设备通过 block layer 接入 VFS。 +- framebuffer console 和 serial log 可以同时存在。 + +## 当前状态 + +未开始。 + +进入本阶段前,需要中断、内存、调度、VFS 和基础用户态足够稳定。 + +## 后续扩展 + +- APIC/IOAPIC。 +- MSI/MSI-X。 +- HPET。 +- PCIe capability。 +- DMA mapping。 +- USB host controller 和 HID/storage。 +- virtio-net 和基础网络栈。 +- framebuffer/GOP console。 +- 音频。 +- 电源管理、热插拔、CPU topology、NUMA。 diff --git a/docs/agents/tasks/10-real-machine.md b/docs/agents/tasks/10-real-machine.md index d31ebe5..0319609 100644 --- a/docs/agents/tasks/10-real-machine.md +++ b/docs/agents/tasks/10-real-machine.md @@ -23,16 +23,76 @@ - 验证 Secure Boot、启动项、磁盘枚举等风险。 - 先从 U 盘启动,再考虑本机启动项。 +### 1. Boot media and rollback + +- 先制作可移除 U 盘或镜像,不修改本机现有 EFI 启动项。 +- 记录制作步骤、分区布局、FAT 文件路径和 bootloader 文件名。 +- 每次真机尝试都要能回退到原系统启动。 +- 不在未验证前写入内置磁盘 EFI 分区。 + +### 2. Hardware inventory + +- 在 `docs/host-machine.md` 记录 CPU、内存、UEFI 固件版本、Secure Boot 状态、显卡、存储控制器、键盘路径和可用输出设备。 +- 区分 QEMU/OVMF 行为和真机 firmware 行为。 +- 记录 ACPI 表、memory map、GOP 模式、串口可用性和启动失败阶段。 +- 不把某台机器的硬件常量写入通用代码。 + +### 3. Diagnostics first + +- 真机路径优先保证 early log、panic、异常日志和阶段 marker。 +- 如果没有串口,需要 framebuffer console 或屏幕阶段输出作为 fallback。 +- 每个启动阶段都输出可识别 marker:bootloader entry、memory map、ExitBootServices、kernel entry、GDT/IDT、heap、timer。 +- 失败报告要能判断停在 firmware、bootloader、ExitBootServices、kernel entry、异常或中断阶段。 + +### 4. Firmware and security differences + +- Secure Boot 默认视为风险项,先记录状态,不绕过用户安全设置。 +- UEFI memory map、runtime service、GOP、文件路径大小写和磁盘枚举可能和 OVMF 不同。 +- 真机测试要优先只读硬件信息,避免早期驱动写危险寄存器。 +- 后续 ACPI/PCI 支持进入前,真机功能目标应限于启动和诊断。 + +## Linux 参考原则 + +- 参考 Linux bring-up 流程:先保证早期日志和异常诊断,再逐步打开中断、内存、驱动。 +- 参考 Linux platform quirk 思路:硬件差异要记录和隔离,不把单机 workaround 扩散到通用路径。 +- 参考 Linux boot parameters/firmware handoff 思路:firmware 输入要保存、校验和转换为内核自己的模型。 +- 参考 Linux console fallback 思路:serial、early console、framebuffer console 互相补位。 + ## 非玩具化约束 - 早期不修改本机现有启动链。 - 真机相关信息只放在 `docs/host-machine.md`。 - 真机失败必须能通过日志定位到阶段。 - 不能把某台机器的硬件假设写进通用代码。 +- 不在未确认目标磁盘前写入内置磁盘或 EFI 分区。 +- Secure Boot 相关操作必须记录风险,不默认要求关闭。 +- 真机 workaround 必须有注释和硬件记录,不能伪装成通用逻辑。 +- QEMU 测试仍然是回归基线,真机修复不能破坏 OVMF 路径。 +- 真机测试脚本应尽量只生成介质,不自动执行危险写盘操作。 ## 验收方式 - U 盘可进入 Tianole bootloader。 - kernel 能启动并输出阶段日志。 - 失败时能判断停在 bootloader、ExitBootServices、kernel entry 还是异常路径。 +- `docs/host-machine.md` 记录一次完整尝试,包括硬件信息、固件设置、镜像版本和结果。 +- OVMF 回归仍通过。 +- 真机至少能输出到一种可观察通道:串口、屏幕或持久日志。 +- 启动失败时有最后阶段 marker。 +- 不修改本机默认启动项也能完成测试。 +## 当前状态 + +未开始。 + +进入本阶段前,QEMU + OVMF 的早期日志、异常、内存和调度路径应稳定。 + +## 后续扩展 + +- 真机串口或 USB debug。 +- framebuffer console。 +- ACPI 表 dump。 +- PCI 枚举对比。 +- Secure Boot 签名流程。 +- 多机器兼容性记录。 +- 自动化镜像制作和校验。 diff --git a/docs/agents/tasks/README.md b/docs/agents/tasks/README.md index 35c41bf..f0c69e2 100644 --- a/docs/agents/tasks/README.md +++ b/docs/agents/tasks/README.md @@ -28,7 +28,7 @@ | `01-early-debug.md` | 基础完成 | 已有 early log 前端、QEMU debug port、COM1 串口和最小 `panic()`。 | | `02-cpu-interrupts.md` | 基础完成 | 已有 GDT/TSS/IDT、exception vector 0-31、`trap_frame` 和 invalid opcode 回归测试。 | | `03-memory.md` | 基础完成 | 已有最小物理页 allocator、页表 map/unmap/query、page fault 诊断和内核堆。 | -| `04-time-scheduler.md` | 进行中 | 已有 PIT timer interrupt、通用 tick、kernel thread、内核栈、上下文切换、timer 驱动 round-robin、sleep 和 wait queue 基础;锁、退出回收和更严格的中断返回调度未完成。 | +| `04-time-scheduler.md` | 进行中 | 已有 PIT timer interrupt、通用 tick、kernel thread、内核栈、上下文切换、timer 驱动 round-robin、sleep、wait queue、条件等待、timeout 等待、基础 interrupt-safe lock、IRQ exit reschedule 和最小 DEAD 回收;下一步要收紧 wait queue 锁语义、线程生命周期和 trap-frame aware interrupt-exit reschedule。 | | `05-input-events.md` | 未开始 | 需要输入事件模型和键盘接入。 | | `06-storage-vfs.md` | 未开始 | 需要块层、缓存、VFS 和基础文件系统。 | | `07-user-mode.md` | 未开始 | 需要 syscall、进程、用户地址空间和 ELF 加载。 | @@ -36,7 +36,7 @@ | `09-driver-expansion.md` | 未开始 | 需要设备模型、PCI/ACPI、存储、网络等驱动扩展。 | | `10-real-machine.md` | 未开始 | 需要 U 盘真机启动验证和硬件差异记录。 | -当前最合适的下一步仍在 `04-time-scheduler.md` 内:补 interrupt-safe lock、线程退出回收,并把调度路径收敛为更明确的 interrupt-exit reschedule。 +当前最合适的下一步仍在 `04-time-scheduler.md` 内:先把 wait queue 条件检查、wakeup、timeout 和锁规则补成不会丢唤醒的模型,再收紧线程生命周期和更明确的 interrupt-exit reschedule。`05-input-events.md` 的键盘驱动应等这些边界稳定后再开始。 ## Linux 级能力缺口路由