docs(tasks): expand staged kernel roadmap

This commit is contained in:
Microindole 2026-05-12 16:53:33 +08:00
parent 288d55fb60
commit 61775e86e9
No known key found for this signature in database
GPG Key ID: 22FB34CD2133ACA1
11 changed files with 663 additions and 13 deletions

View File

@ -25,18 +25,53 @@
- 增加最小 `panic()`panic 后停止 CPU。 - 增加最小 `panic()`panic 后停止 CPU。
- 为后续 printk、oops、内核符号和 crash dump 预留接口边界。 - 为后续 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 信息。
- 预留多 consumerserial、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。
- COM1 端口号要集中定义,不能散落在业务代码。 - COM1 端口号要集中定义,不能散落在业务代码。
- panic 路径不能依赖动态内存。 - panic 路径不能依赖动态内存。
- 输出接口要允许后续接 framebuffer console。 - 输出接口要允许后续接 framebuffer console。
- 日志接口不能要求 scheduler、heap 或 interrupt 已经初始化。
- panic/oops 策略不能写进异常入口汇编。
- 正式 printk 出现后early log 调用方不能被迫大规模改名或换接口。
- 任何新增 backend 都不能影响其他 backend 的可用性。
## 验收方式 ## 验收方式
- QEMU 日志中能看到 bootloader 和 kernel 输出。 - QEMU 日志中能看到 bootloader 和 kernel 输出。
- 串口或 debug log 中能看到 `boot services exited` - 串口或 debug log 中能看到 `boot services exited`
- 人为触发 panic 时能看到 panic 信息并停止。 - 人为触发 panic 时能看到 panic 信息并停止。
- 禁用某一个输出 backend 时,其他 backend 仍可输出关键日志。
- panic 路径在 heap 未初始化前也能输出。
- `scripts/check.sh` 至少验证 debug log 和 serial log 两条路径。
## 当前状态 ## 当前状态
@ -55,6 +90,9 @@
- 内核符号化输出。 - 内核符号化输出。
- framebuffer console。 - framebuffer console。
- crash dump。 - crash dump。
- early log 到 printk 的接管流程。
- panic 后保留最后日志的内存 buffer。
- 多 CPU 后的日志串行化规则。
验收依据: 验收依据:

View File

@ -26,6 +26,41 @@
- 之后再接 PIC/APIC 和 IRQ。 - 之后再接 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 的入口可共享框架,但语义要区分。 - exception 和 IRQ 的入口可共享框架,但语义要区分。
- 不把中断处理写进 `kernel/main.c` - 不把中断处理写进 `kernel/main.c`
- oops/panic 策略要和 trap 分发分离。 - oops/panic 策略要和 trap 分发分离。
- IRQ handler 注册、EOI 和调度请求不能互相混在一个设备专用路径里。
- 用户态异常策略要提前预留,不能默认所有异常都 panic。
- arch 层可以知道 vector 和 gate通用层不应知道 IDT 编码细节。
- double fault 等严重异常不能长期依赖普通内核栈。
## 验收方式 ## 验收方式
- 主动触发 invalid opcode 或 divide error。 - 主动触发 invalid opcode 或 divide error。
- 日志输出 vector、rip、rsp、error code。 - 日志输出 vector、rip、rsp、error code。
- 未处理异常进入 panic。 - 未处理异常进入 panic。
- 外部 IRQ vector 和 CPU exception vector 不冲突。
- IRQ handler 可注册和分发,设备逻辑不在 trap dispatch 中硬编码。
- page fault 路径能输出 fault address 和访问来源。
- 后续用户态异常可以在不重写 trap frame 的前提下接入。
## 当前状态 ## 当前状态
@ -63,6 +106,9 @@
- 用户态异常返回。 - 用户态异常返回。
- 可恢复异常处理。 - 可恢复异常处理。
- oops 格式和符号化输出。 - oops 格式和符号化输出。
- syscall/sysret 或 int syscall 入口。
- nested interrupt 和 preempt/reschedule 边界。
- NMI、spurious IRQ 和未知 vector 策略。
验收依据: 验收依据:

View File

@ -28,6 +28,48 @@
- 建立最小内核堆。 - 建立最小内核堆。
- 为后续匿名页、缺页加载、COW、`mmap`、page cache、换页预留接口。 - 为后续匿名页、缺页加载、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 和匿名页排除在长期模型之外。 - 不能把 page cache 和匿名页排除在长期模型之外。
- 页表实现不能混入启动 selftest 或具体业务逻辑。
- 通用 MM 接口不能暴露 x86 页表 flag 编码。
- page fault 诊断和 page fault 策略要分离。
- 内核堆失败路径必须被调用方看见,不能默认分配永远成功。
## 验收方式 ## 验收方式
@ -45,6 +91,10 @@
- page fault 能输出有效诊断。 - page fault 能输出有效诊断。
- 内核堆能分配小对象。 - 内核堆能分配小对象。
- 后续能在此基础上加入 COW、`mmap`、换页和内存回收。 - 后续能在此基础上加入 COW、`mmap`、换页和内存回收。
- 页表 selftest 不和页表主实现混在同一文件职责内。
- `kmalloc()`/`kfree()` 有基础复用验证。
- page fault 测试能区分 not-present、权限和访问类型。
- 后续添加用户地址空间时不需要重写物理页 allocator。
## 当前状态 ## 当前状态
@ -70,6 +120,12 @@
- page metadata。 - page metadata。
- buddy allocator。 - buddy allocator。
- slab/slub 或等价小对象缓存。 - slab/slub 或等价小对象缓存。
- VMA 或等价虚拟区域管理。
- 用户地址空间创建、复制和销毁。
- COW、匿名页和文件页。
- page cache、writeback 和内存回收。
- swap 或等价换页机制。
- DMA 可用内存和 MMIO 映射边界。
验收依据: 验收依据:

View File

@ -23,13 +23,80 @@
## 实现内容 ## 实现内容
- 建立 kernel thread。 ### 1. Timer 与时钟基础
- 建立上下文切换。
- 建立 run queue。 - 接入一个可替换的硬件 timer 后端,当前可以先用 PIT periodic timer。
- 建立 sleep/wakeup。 - 通用层只暴露 `timer_tick()`、`timer_ticks()` 和后续 timeout/timer callback 所需接口。
- 建立基础 spinlock 或 interrupt-safe lock。 - 调度器不能直接读取 PIT/APIC 硬件细节,只能依赖通用 time/timer 层。
- 接入 timer tick 或 one-shot timer。 - tick handler 中只做短路径工作:更新时间、唤醒到期 sleep、标记 reschedule不在 IRQ handler 内做复杂策略。
- 为 workqueue、deferred work、completion、引用计数生命周期管理预留位置。 - 后续预留 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 唤醒。 - 线程可以 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 模型,避免把普通线程栈切换入口长期当成完整抢占式切换。 ### A. 调度状态机收紧
- 继续扩大 interrupt-safe lock 覆盖范围,明确可睡眠路径和不可睡眠路径的锁规则。
- 为 wait queue 增加更严格的状态检查,并把条件检查与 wakeup 边界纳入明确锁规则。 - 明确合法状态转换,例如 `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` 的键盘驱动实现。

View File

@ -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。 - 键盘驱动只产生事件,不直接操作 shell。
- 键盘布局要可替换。 - 键盘布局要可替换。
- 输入队列接口要允许未来接 USB HID。 - 输入队列接口要允许未来接 USB HID。
- 中断 handler 中不要做复杂处理。 - 中断 handler 中不要做复杂处理。
- input core 不依赖 PS/2PS/2 driver 不依赖 terminal。
- event queue 要有锁和等待语义,不能靠忙等读取。
- 事件丢失、队列满和未知 scancode 必须可观测。
- blocking read 必须通过 wait queue 或等价机制睡眠,不能轮询。
- terminal 控制字符和 shell 命令解析不能写进 keyboard driver。
## 验收方式 ## 验收方式
- 按键触发中断。 - 按键触发中断。
- kernel 能读取 key event。 - kernel 能读取 key event。
- 后续 shell 可复用同一输入接口。 - 后续 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。

View File

@ -27,6 +27,48 @@
- 后续再加入 write 和持久化文件系统。 - 后续再加入 write 和持久化文件系统。
- 为 page cache、block cache、writeback 和崩溃一致性预留边界。 - 为 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 不依赖某个具体文件系统。 - VFS 不依赖某个具体文件系统。
@ -35,6 +77,11 @@
- 缓存层不能和具体磁盘驱动耦合。 - 缓存层不能和具体磁盘驱动耦合。
- VFS 对象生命周期必须明确,不能靠全局静态对象规避释放问题。 - VFS 对象生命周期必须明确,不能靠全局静态对象规避释放问题。
- 文件权限、时间戳、inode 编号等 POSIX 语义要保留位置。 - 文件权限、时间戳、inode 编号等 POSIX 语义要保留位置。
- open file 和 inode 不能混成同一个对象。
- VFS 错误要能映射到后续用户态 errno。
- read/write 不能只服务 demo 文件,必须处理 offset、EOF 和短读。
- 文件系统 selftest 不能依赖 shell 已经存在。
- 后续可写路径不能要求重写只读 VFS API。
## 验收方式 ## 验收方式
@ -42,3 +89,25 @@
- 可列出目录。 - 可列出目录。
- 替换具体 FS 不影响 VFS 调用方。 - 替换具体 FS 不影响 VFS 调用方。
- 后续能加入可写缓存和 writeback而不重写 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 文件接口。

View File

@ -28,6 +28,49 @@
- 为 POSIX syscall、`fcntl/stat/chmod`、signal、pipe、socket、eventfd、futex、共享内存、poll/select 和 IPC 预留 ABI 边界。 - 为 POSIX syscall、`fcntl/stat/chmod`、signal、pipe、socket、eventfd、futex、共享内存、poll/select 和 IPC 预留 ABI 边界。
- 为 uid/gid、用户/组、文件权限、进程权限、capability 或等价隔离模型预留进程凭据结构。 - 为 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 ABIsyscall number 和参数规则稳定libc 可以独立绑定。
- 参考 Linux ELF loaderVFS 提供文件loader 校验 program header 并建立用户映射。
- 参考 Linux user access helpers所有用户指针都要复制/检查,不能直接信任。
- 参考 Linux wait/exit/zombie 模型:进程退出和资源释放分阶段完成。
## 非玩具化约束 ## 非玩具化约束
- syscall 表要稳定记录。 - syscall 表要稳定记录。
@ -37,6 +80,11 @@
- syscall 不能只按当前 demo 程序硬编码。 - syscall 不能只按当前 demo 程序硬编码。
- 进程资源释放必须有明确所有权和引用计数规则。 - 进程资源释放必须有明确所有权和引用计数规则。
- `fork/exec/wait`、signal、pipe、poll/select 是运行复杂 Unix 程序的关键路径,不能被路线遗漏。 - `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 能回收用户进程资源。 - kernel 能回收用户进程资源。
- 非法用户访问能进入异常处理并终止进程。 - 非法用户访问能进入异常处理并终止进程。
- syscall ABI 文档化,后续可以被 libc 绑定。 - 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 或基础调试接口。

View File

@ -27,6 +27,48 @@
- 为 tty、session、job control 留出后续位置。 - 为 tty、session、job control 留出后续位置。
- 为 procfs/sysfs/debugfs、ftrace、perf、crash dump 类可观测接口预留路径。 - 为 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 必须运行在用户态。 - shell 必须运行在用户态。
@ -35,6 +77,11 @@
- 工具能力应服务于后续 git 移植。 - 工具能力应服务于后续 git 移植。
- shell 不是内核调试器,不能用 shell 规避系统调用和 VFS 的缺失。 - shell 不是内核调试器,不能用 shell 规避系统调用和 VFS 的缺失。
- `git` 目标至少需要可用 libc、文件状态、权限、时间、路径、进程等待等接口。 - `git` 目标至少需要可用 libc、文件状态、权限、时间、路径、进程等待等接口。
- init、shell、基础命令不能混成一个二进制除非接口仍保持独立。
- 外部命令必须走进程创建和 VFS 加载路径。
- 用户态工具不能包含 kernel 私有结构体布局。
- 调试接口要只读优先,避免早期工具直接修改 kernel 状态。
- 缺失能力应补 syscall/libc/VFS而不是给单个命令加后门。
## 验收方式 ## 验收方式
@ -43,3 +90,25 @@
- shell 能执行至少两个外部命令。 - shell 能执行至少两个外部命令。
- 命令可访问 VFS。 - 命令可访问 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 移植所需的文件、时间、权限和进程接口。

View File

@ -35,6 +35,50 @@
- 后续再做网络和音频。 - 后续再做网络和音频。
- 规划 socket API 和网络栈接入点,但本地 git 阶段不要求网络。 - 规划 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 modeldevice/driver/bus/resource 分层probe/remove 管理生命周期。
- 参考 Linux PCI/ACPI 分层:平台发现和具体驱动分开,驱动通过抽象资源访问硬件。
- 参考 Linux irqchip/irqdomain 思路:设备驱动不直接管理 CPU vector。
- 参考 Linux DMA mapping 思路DMA 地址能力和缓存一致性不能被驱动随意假设。
- 参考 Linux driver core新驱动应插入框架不要求修改 VFS、shell、调度器等无关层。
## 非玩具化约束 ## 非玩具化约束
- 设备发现、驱动 probe、资源分配要分层。 - 设备发现、驱动 probe、资源分配要分层。
@ -43,6 +87,11 @@
- 新驱动不能要求修改 shell、VFS、调度器等无关层。 - 新驱动不能要求修改 shell、VFS、调度器等无关层。
- 硬件发现、资源分配和驱动绑定必须从设备模型进入,不能由单个驱动私自扫描全部硬件。 - 硬件发现、资源分配和驱动绑定必须从设备模型进入,不能由单个驱动私自扫描全部硬件。
- ACPI/PCI/Device Tree 类平台信息要隔离在平台层,不能泄漏到通用子系统。 - ACPI/PCI/Device Tree 类平台信息要隔离在平台层,不能泄漏到通用子系统。
- probe 失败必须释放已申请资源。
- 驱动不能长期 busy wait应使用 IRQ、wait queue 或 deferred work。
- DMA 不能假设所有物理内存都可寻址或缓存一致。
- 平台设备不能把某台机器的 ACPI 表布局写死进通用代码。
- QEMU 专用设备支持不能破坏真机路径。
## 验收方式 ## 验收方式
@ -50,3 +99,27 @@
- 至少一种块设备可接入 VFS。 - 至少一种块设备可接入 VFS。
- 新驱动加入时只影响对应驱动和通用驱动框架。 - 新驱动加入时只影响对应驱动和通用驱动框架。
- 后续可接入网络、USB、音频而不重写已有核心子系统。 - 后续可接入网络、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。

View File

@ -23,16 +23,76 @@
- 验证 Secure Boot、启动项、磁盘枚举等风险。 - 验证 Secure Boot、启动项、磁盘枚举等风险。
- 先从 U 盘启动,再考虑本机启动项。 - 先从 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。
- 每个启动阶段都输出可识别 markerbootloader 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` - 真机相关信息只放在 `docs/host-machine.md`
- 真机失败必须能通过日志定位到阶段。 - 真机失败必须能通过日志定位到阶段。
- 不能把某台机器的硬件假设写进通用代码。 - 不能把某台机器的硬件假设写进通用代码。
- 不在未确认目标磁盘前写入内置磁盘或 EFI 分区。
- Secure Boot 相关操作必须记录风险,不默认要求关闭。
- 真机 workaround 必须有注释和硬件记录,不能伪装成通用逻辑。
- QEMU 测试仍然是回归基线,真机修复不能破坏 OVMF 路径。
- 真机测试脚本应尽量只生成介质,不自动执行危险写盘操作。
## 验收方式 ## 验收方式
- U 盘可进入 Tianole bootloader。 - U 盘可进入 Tianole bootloader。
- kernel 能启动并输出阶段日志。 - kernel 能启动并输出阶段日志。
- 失败时能判断停在 bootloader、ExitBootServices、kernel entry 还是异常路径。 - 失败时能判断停在 bootloader、ExitBootServices、kernel entry 还是异常路径。
- `docs/host-machine.md` 记录一次完整尝试,包括硬件信息、固件设置、镜像版本和结果。
- OVMF 回归仍通过。
- 真机至少能输出到一种可观察通道:串口、屏幕或持久日志。
- 启动失败时有最后阶段 marker。
- 不修改本机默认启动项也能完成测试。
## 当前状态
未开始。
进入本阶段前QEMU + OVMF 的早期日志、异常、内存和调度路径应稳定。
## 后续扩展
- 真机串口或 USB debug。
- framebuffer console。
- ACPI 表 dump。
- PCI 枚举对比。
- Secure Boot 签名流程。
- 多机器兼容性记录。
- 自动化镜像制作和校验。

View File

@ -28,7 +28,7 @@
| `01-early-debug.md` | 基础完成 | 已有 early log 前端、QEMU debug port、COM1 串口和最小 `panic()`。 | | `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 回归测试。 | | `02-cpu-interrupts.md` | 基础完成 | 已有 GDT/TSS/IDT、exception vector 0-31、`trap_frame` 和 invalid opcode 回归测试。 |
| `03-memory.md` | 基础完成 | 已有最小物理页 allocator、页表 map/unmap/query、page fault 诊断和内核堆。 | | `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` | 未开始 | 需要输入事件模型和键盘接入。 | | `05-input-events.md` | 未开始 | 需要输入事件模型和键盘接入。 |
| `06-storage-vfs.md` | 未开始 | 需要块层、缓存、VFS 和基础文件系统。 | | `06-storage-vfs.md` | 未开始 | 需要块层、缓存、VFS 和基础文件系统。 |
| `07-user-mode.md` | 未开始 | 需要 syscall、进程、用户地址空间和 ELF 加载。 | | `07-user-mode.md` | 未开始 | 需要 syscall、进程、用户地址空间和 ELF 加载。 |
@ -36,7 +36,7 @@
| `09-driver-expansion.md` | 未开始 | 需要设备模型、PCI/ACPI、存储、网络等驱动扩展。 | | `09-driver-expansion.md` | 未开始 | 需要设备模型、PCI/ACPI、存储、网络等驱动扩展。 |
| `10-real-machine.md` | 未开始 | 需要 U 盘真机启动验证和硬件差异记录。 | | `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 级能力缺口路由 ## Linux 级能力缺口路由