docs: 添加项目文档体系(架构/启动路线/路线图/贡献规范)
- docs/ARCHITECTURE.md: 架构设计文档,覆盖五大核心子系统 (SAS-R0-PCQ/UTSM/UTRW/DRR/DKM)、内存模型、驱动/文件/网络/图形子系统、 开放设计点 - docs/BOOT_SEQUENCE.md: 启动路线设计,原创 DBS 五阶段命名体系 (B0 Ignis/B1 Sigillum/B2 Transitus/B3 Origo/B4 Excitas), 启动契约/锚点/回退链机制 - docs/ROADMAP.md: 分阶段开发路线图,9 个 Phase + 5 个里程碑 - CONTRIBUTING.md: 贡献与协作规范,含代码规范/Git 工作流/PR 流程 - .github/: PR 模板 + Bug/Feature Issue 模板 - README.md: 更新为项目介绍 + 文档索引 + 构建说明 所有文档基于项目真实源码与设计文档编写,62 个交叉链接全部有效。
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Bug 报告
|
||||
about: 报告内核崩溃、驱动故障、构建失败等问题
|
||||
title: "[bug] "
|
||||
labels: bug
|
||||
---
|
||||
|
||||
## 问题描述
|
||||
|
||||
<!-- 简要描述问题 -->
|
||||
|
||||
## 复现步骤
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
## 预期行为
|
||||
|
||||
<!-- 应该发生什么 -->
|
||||
|
||||
## 实际行为
|
||||
|
||||
<!-- 实际发生了什么 -->
|
||||
|
||||
## 环境
|
||||
|
||||
- 组件:<!-- UTSM / DSK / DKM:<驱动名> / FirstInit / 构建 -->
|
||||
- 运行环境:<!-- QEMU / 真机 -->
|
||||
- QEMU 参数(如非默认):
|
||||
|
||||
## 串口日志
|
||||
|
||||
```
|
||||
<!-- 粘贴 QEMU 串口输出,至少包含崩溃点前后上下文 -->
|
||||
```
|
||||
|
||||
## 崩溃分析(如适用)
|
||||
|
||||
<!-- 三重故障 / page fault / panic 时的寄存器、栈、调用上下文 -->
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: 功能请求
|
||||
about: 提议新驱动、新子系统或架构改进
|
||||
title: "[feat] "
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
## 功能描述
|
||||
|
||||
<!-- 简要描述提议的功能 -->
|
||||
|
||||
## 动机
|
||||
|
||||
<!-- 为什么需要这个功能,解决什么问题 -->
|
||||
|
||||
## 涉及子系统
|
||||
|
||||
- [ ] UTSM 首阶段内核
|
||||
- [ ] DSK 主内核
|
||||
- [ ] DKM 驱动
|
||||
- [ ] 内存管理
|
||||
- [ ] 文件系统 / VFS
|
||||
- [ ] 网络
|
||||
- [ ] 调度器 (SAS-R0-PCQ)
|
||||
- [ ] 恢复系统 (DRR)
|
||||
- [ ] FirstInit / 用户空间
|
||||
- [ ] 文档
|
||||
|
||||
## 设计思路
|
||||
|
||||
<!-- 描述实现方案,如有 ABI / 架构影响请重点说明 -->
|
||||
|
||||
## 路线图对应
|
||||
|
||||
<!-- 对应 docs/ROADMAP.md 中的哪个 Phase?(如适用) -->
|
||||
|
||||
## 验收标准
|
||||
|
||||
<!-- 完成后如何验证 -->
|
||||
@@ -0,0 +1,52 @@
|
||||
## 变更说明
|
||||
|
||||
<!-- 简要描述本 PR 做了什么、为什么 -->
|
||||
|
||||
## 变更类型
|
||||
|
||||
- [ ] feat — 新功能
|
||||
- [ ] fix — 修复
|
||||
- [ ] docs — 文档
|
||||
- [ ] build — 构建系统
|
||||
- [ ] refactor — 重构
|
||||
- [ ] test — 测试
|
||||
- [ ] chore — 杂项
|
||||
|
||||
## 影响范围
|
||||
|
||||
<!-- 勾选受影响的子系统 -->
|
||||
- [ ] UTSM 首阶段内核
|
||||
- [ ] DSK 主内核
|
||||
- [ ] DKM 驱动(请列出具体驱动: )
|
||||
- [ ] DKM ABI / kernel_api
|
||||
- [ ] 文件系统 / VFS
|
||||
- [ ] 网络
|
||||
- [ ] FirstInit / 用户空间
|
||||
- [ ] 构建 / 镜像打包
|
||||
- [ ] 文档
|
||||
|
||||
## 提交前检查清单
|
||||
|
||||
- [ ] `.\build.bat` 构建成功,产出 `ISO/deshab.img`
|
||||
- [ ] `.\ISO\run_qemu.bat` 启动到 `[DSK] SELFTEST PASS`
|
||||
- [ ] 无新增编译 warning(`-Wall -Wextra`)
|
||||
- [ ] ABI 变更已同步所有驱动本地定义(未在结构体中间插入字段)
|
||||
- [ ] 新驱动已在 `manifest.json` + `limine.conf` 注册
|
||||
- [ ] 设计文档(`RE/`)与模块 README 已同步
|
||||
- [ ] 提交信息符合 Conventional Commits
|
||||
- [ ] `LESSONS_LEARNED.md` 已追加经验记录(如适用)
|
||||
|
||||
## 测试方式
|
||||
|
||||
<!-- 描述如何验证本变更,如 QEMU 参数、预期串口输出 -->
|
||||
|
||||
```text
|
||||
预期输出:
|
||||
```
|
||||
|
||||
## ABI / 兼容性影响
|
||||
|
||||
<!-- 如果修改了 dkm_kernel_api、driver_desc、dsk_boot_context 等 ABI,请说明:
|
||||
1. 新增字段是否追加到结构尾部
|
||||
2. 是否影响已有驱动
|
||||
3. min_kernel_abi / abi_version 是否需要变更 -->
|
||||
+322
@@ -0,0 +1,322 @@
|
||||
# 贡献与协作规范
|
||||
|
||||
感谢你参与 Deshab-OS 的开发!本文档定义了开发环境、代码规范、Git 工作流与测试验证流程,确保所有贡献遵循统一的工程标准。
|
||||
|
||||
> 操作系统开发容错率极低,一行错误的内联汇编或 ABI 字段偏移就可能导致三重故障。请严格遵守以下规范。
|
||||
|
||||
---
|
||||
|
||||
## 1. 开发环境
|
||||
|
||||
### 1.1 必需工具链
|
||||
|
||||
| 工具 | 版本要求 | 用途 |
|
||||
|------|---------|------|
|
||||
| **LLVM Clang** | 14+ | C11 / 汇编编译(`-target x86_64-unknown-none`) |
|
||||
| **ld.lld** | 14+ | 链接器(内核 ELF + 驱动 `.drv`) |
|
||||
| **make** | 任意 | 各模块 MAKEFILE |
|
||||
| **Python 3** | 3.8+ | 字体生成(`mkfont.py`) |
|
||||
| **Pillow** | 最新 | Python 图像库(`pip install Pillow`) |
|
||||
| **QEMU** | 7+ | `qemu-system-x86_64`,UEFI 启动验证 |
|
||||
| **PowerShell** | 5.1+ | `build.ps1` 构建 + GPT/FAT32 镜像打包 |
|
||||
|
||||
> `build.ps1` 会自动扫描 `C:\Program Files\LLVM\bin` 等常见目录发现 clang/ld.lld,即使不在 PATH 也可用。
|
||||
|
||||
### 1.2 可选工具
|
||||
|
||||
- **Limine**:引导器(`SYSTEM/EFI/BOOT/BOOTX64.EFI` 已内置)
|
||||
- **xxd / hexdump**:二进制镜像校验(MBR `AA55`、GPT `EFI PART`、FAT32 标记)
|
||||
|
||||
### 1.3 环境验证
|
||||
|
||||
```powershell
|
||||
# 完整构建
|
||||
.\build.bat
|
||||
|
||||
# 应产出:
|
||||
# SYSTEM/boot/utsm.elf
|
||||
# SYSTEM/system/deshab64/deshab.elf
|
||||
# SYSTEM/driver/**/*.drv(14 个)
|
||||
# ISO/deshab.img(GPT + FAT32 ESP)
|
||||
|
||||
# QEMU 启动验证
|
||||
.\ISO\run_qemu.bat
|
||||
# 串口输出应看到:
|
||||
# [UTSM] boot → ... → [UTSM] SELFTEST PASS → [UTSM] loading DSK → [DSK] boot → [DSK] SELFTEST PASS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 目录结构约定
|
||||
|
||||
```text
|
||||
CODE/ 源码(只放源码,不放产物)
|
||||
├── UTSM/ 首阶段内核(→ SYSTEM/boot/utsm.elf)
|
||||
├── dsk/ DSK 主内核(→ SYSTEM/system/deshab64/deshab.elf)
|
||||
├── DKM/ 驱动源码(每个驱动一个子目录 → SYSTEM/driver/<class>/<name>.drv)
|
||||
├── firstInit/ 用户设置向导(→ SYSTEM/system/user/use/FirstInit.elf)
|
||||
├── mouse/ 鼠标初始化器(→ SYSTEM/system/deshab64/mouse/mouseInit.elf)
|
||||
├── netman/ 网络管理器(→ SYSTEM/system/deshab64/network/netman.elf)
|
||||
└── font/ 字体工具(→ SYSTEM/system/font/*.dbf)
|
||||
|
||||
SYSTEM/ 打包产物(IMG 根目录,提交到仓库供构建使用)
|
||||
├── boot/ 引导模块
|
||||
├── driver/ *.drv + manifest.json
|
||||
├── system/ 主内核 + 字体 + 用户程序
|
||||
└── EFI/BOOT/ UEFI 引导
|
||||
|
||||
RE/ 研究与设计文档(架构/算法/ABI 规范)
|
||||
docs/ 项目文档(架构总览/路线图)
|
||||
```
|
||||
|
||||
**约定**:
|
||||
|
||||
- `CODE/` 只放源码,`SYSTEM/` 放构建产物。修改源码后必须重新构建并更新 `SYSTEM/` 下的产物。
|
||||
- `*.o` 中间文件不应提交(各 MAKEFILE 产物)。`.gitignore` 已忽略 `ISO/deshab.img`。
|
||||
- 新增驱动必须在 `SYSTEM/driver/manifest.json` 注册,并在 `limine.conf` 添加 `module_path`。
|
||||
- 新增子系统设计文档放 `RE/`,项目级文档放 `docs/`。
|
||||
|
||||
---
|
||||
|
||||
## 3. 代码规范
|
||||
|
||||
### 3.1 C 代码
|
||||
|
||||
**编译标志**(内核与驱动统一,源自 `build.ps1`):
|
||||
|
||||
```text
|
||||
-target x86_64-unknown-none -std=c11 -ffreestanding -fno-builtin
|
||||
-fno-stack-protector -fno-pic -fno-pie -mcmodel=kernel
|
||||
-mno-red-zone -mno-sse -mno-sse2 -mno-mmx -msoft-float -m64
|
||||
-Wall -Wextra -O2
|
||||
```
|
||||
|
||||
**强制规则**:
|
||||
|
||||
1. **进入 C 前必须 `cli` 和 `cld`**——未建 IDT 前被中断或方向标志异常会导致三重故障。
|
||||
2. **未启用 FPU/SSE 前禁止生成 SIMD 指令**——Clang 在 freestanding 下也可能生成 `xorps/movups`,必须用 `-mno-sse -mno-sse2 -mno-mmx -msoft-float`。
|
||||
3. **高半区内核必须用 `-mcmodel=kernel`**——否则 `R_X86_64_32 out of range`。
|
||||
4. **`driver_desc` 必须是 global**——`__attribute__((visibility("default")))`,否则 symtab 中为 LOCAL,loader 找不到。
|
||||
5. **不要用 `__attribute__((unused))` 标记需要被调用的函数**——在 `-O2` 下可能被优化掉,导致运行时崩溃。
|
||||
6. **ABI 结构体字段只能追加,不能插入**——`dkm_kernel_api` 新增字段必须追加到结构尾部,否则改变已有驱动本地 ABI 偏移。
|
||||
7. **日志必须带稳定模块前缀**——如 `[UTSM]`、`[DKM:ahci]`、`[DSK]`,便于 QEMU 日志过滤。
|
||||
|
||||
**代码风格**:
|
||||
|
||||
- 4 空格缩进,`{` 同行(K&R 风格)。
|
||||
- 函数/变量命名 `snake_case`,宏/常量 `UPPER_SNAKE_CASE`。
|
||||
- 结构体用 `typedef struct { ... } name_t;`,类型后缀 `_t`。
|
||||
- 内联汇编约束严格验证(如 `rdmsr =A` 在真机会失败,QEMU 侥幸能工作)。
|
||||
|
||||
### 3.2 汇编
|
||||
|
||||
- 汇编入口文件命名避免与 C 同名(`idt.S` 和 `idt.c` 同名会输出冲突的 `idt.o`,应拆为 `idt_stubs.S`)。
|
||||
- 中断 stub 宏必须显式区分是否自动压入 error code,否则破坏统一栈帧导致 `iretq` 失败。
|
||||
- Limine request 必须放入 `.limine_requests*` 区段,linker script 显式保留 start/request/end。
|
||||
|
||||
### 3.3 驱动开发
|
||||
|
||||
新增 DKM 驱动必须:
|
||||
|
||||
1. 在 `CODE/DKM/<class>/<name>/` 创建源码,导出 `driver_desc` / `driver_init` / `driver_exit`。
|
||||
2. 驱动本地 `dkm_kernel_api` 定义必须与内核侧**字段布局完全一致**(含 padding)。
|
||||
3. 通过 `dkm_kernel_api` 调用内核服务,**不直接依赖任意内核符号**。
|
||||
4. 第一版只支持必要 relocation,禁止 TLS / IFUNC / lazy binding / 外部动态库 / 用户态 libc。
|
||||
5. 在 `SYSTEM/driver/manifest.json` 注册(name / path / class / required / depends / provides)。
|
||||
6. 在 `SYSTEM/boot/limine.conf` 添加 `module_path` 预加载。
|
||||
7. 在 `build.ps1` 的 `Build-DkmDriver` 流程中添加编译目标。
|
||||
8. 更新 [CODE/DKM/README.md](CODE/DKM/README.md) 驱动清单。
|
||||
|
||||
### 3.4 构建脚本
|
||||
|
||||
- 不要用 PowerShell `Set-Content` 写 C 源文件——会产生 BOM(`U+FEFF`),导致 clang 报错 `extraneous closing brace`。
|
||||
- 构建脚本修改编译参数后必须先 `make clean`,否则旧 object 仍按旧参数链接。
|
||||
- 打包 SYSTEM 时过滤 `*.tmp*`,避免旧 `utsm.elf.tmp` 写入镜像。
|
||||
- `ISO/deshab.img` 被 QEMU 占用时打包会失败,重新打包前先关闭 QEMU。
|
||||
|
||||
---
|
||||
|
||||
## 4. Git 工作流
|
||||
|
||||
### 4.1 分支模型
|
||||
|
||||
| 分支 | 用途 |
|
||||
|------|------|
|
||||
| `main` | 稳定主线,始终可构建可启动 |
|
||||
| `feat/<name>` | 功能开发分支 |
|
||||
| `fix/<name>` | 修复分支 |
|
||||
| `docs/<name>` | 文档分支 |
|
||||
|
||||
### 4.2 提交规范
|
||||
|
||||
采用 [Conventional Commits](https://www.conventionalcommits.org/) 格式:
|
||||
|
||||
```text
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
<body>
|
||||
```
|
||||
|
||||
**type**:
|
||||
|
||||
| type | 说明 |
|
||||
|------|------|
|
||||
| `feat` | 新功能(新驱动、新子系统) |
|
||||
| `fix` | 修复 |
|
||||
| `docs` | 文档变更 |
|
||||
| `build` | 构建系统变更 |
|
||||
| `refactor` | 重构(不改行为) |
|
||||
| `test` | 测试 |
|
||||
| `chore` | 杂项 |
|
||||
|
||||
**scope** 示例:`utsm` / `dsk` / `dkm` / `ahci` / `fat32` / `firstInit` / `build`
|
||||
|
||||
**示例**:
|
||||
|
||||
```text
|
||||
feat(dkm/nvme): 实现 NVMe admin queue 与 identify
|
||||
|
||||
- 新增 admin submission/completion queue 分配
|
||||
- 实现 identify controller 命令
|
||||
- 注册 nvme0 block provider
|
||||
|
||||
依赖 Phase 0 高位 PCI MMIO 映射。
|
||||
```
|
||||
|
||||
```text
|
||||
fix(utsm): 修复 rdmsr 内联汇编在真机三重故障
|
||||
|
||||
rdmsr =A 约束在 QEMU 侥幸工作但真机失败,
|
||||
改为显式 eax/edx 输出。
|
||||
```
|
||||
|
||||
### 4.3 提交粒度
|
||||
|
||||
- 一个提交只做一件事。
|
||||
- 内核/驱动变更必须附带构建产物更新(`SYSTEM/` 下的 `.elf` / `.drv`)。
|
||||
- 修改设计文档(`RE/`)应在同一提交更新对应模块 README。
|
||||
- 阶段性成果应在 [LESSONS_LEARNED.md](LESSONS_LEARNED.md) 追加经验记录。
|
||||
|
||||
---
|
||||
|
||||
## 5. Pull Request 流程
|
||||
|
||||
### 5.1 提交前检查清单
|
||||
|
||||
- [ ] `.\build.bat` 构建成功,产出 `ISO/deshab.img`
|
||||
- [ ] `.\ISO\run_qemu.bat` 启动到 `[DSK] SELFTEST PASS`
|
||||
- [ ] 无新增编译 warning(`-Wall -Wextra`)
|
||||
- [ ] ABI 变更已同步所有驱动本地定义
|
||||
- [ ] 新驱动已在 `manifest.json` + `limine.conf` 注册
|
||||
- [ ] 设计文档与 README 已同步
|
||||
- [ ] 提交信息符合 Conventional Commits
|
||||
- [ ] [LESSONS_LEARNED.md](LESSONS_LEARNED.md) 已追加经验记录(如有)
|
||||
|
||||
### 5.2 PR 描述模板
|
||||
|
||||
见 [.github/pull_request_template.md](.github/pull_request_template.md)。
|
||||
|
||||
### 5.3 审查重点
|
||||
|
||||
审查者应重点关注:
|
||||
|
||||
1. **ABI 兼容性**——是否在结构体中间插入字段?
|
||||
2. **早期启动安全**——是否在 IDT 未建前开中断?是否生成 SIMD 指令?
|
||||
3. **DMA 地址正确性**——是否用内核虚拟地址反推物理地址喂给设备?
|
||||
4. **热路径约束**——是否在调度路径做重活(扫描 capability / 计算 MAC / 重加密)?
|
||||
5. **恢复路径独立性**——是否让 DRR 依赖普通堆?
|
||||
6. **日志前缀**——是否带稳定模块前缀?
|
||||
|
||||
---
|
||||
|
||||
## 6. QEMU 测试验证
|
||||
|
||||
### 6.1 默认启动验证
|
||||
|
||||
```powershell
|
||||
.\ISO\run_qemu.bat
|
||||
```
|
||||
|
||||
**预期串口输出**(最小验证标准):
|
||||
|
||||
```text
|
||||
[UTSM] boot
|
||||
[UTSM] SELFTEST PASS
|
||||
[UTSM] loading DSK
|
||||
[DSK] boot
|
||||
[DSK] context ok
|
||||
[DSK] SELFTEST PASS
|
||||
```
|
||||
|
||||
### 6.2 设备测试场景
|
||||
|
||||
不同驱动需要显式挂载测试设备(默认 QEMU 脚本不含):
|
||||
|
||||
| 驱动 | QEMU 参数 | 验证 |
|
||||
|------|----------|------|
|
||||
| ahci | 临时 SATA 测试盘 | `ahci0` block provider 注册,FAT32 读取 |
|
||||
| nvme | `-device nvme` | 探测 `1b36:0010`(register 读取依赖高位 MMIO) |
|
||||
| e1000 | `-device e1000e` | 探测 `8086:10d3`,RX/TX ring `tx=ready rx=ready` |
|
||||
| virtio_net | `-netdev user` + `-device virtio-net-pci` | 探测 `1af4:1001` |
|
||||
|
||||
> 加入多个网卡会改变 PCI 拓扑,驱动必须把"设备未找到"视为 optional 正常路径。
|
||||
|
||||
### 6.3 真机测试注意
|
||||
|
||||
QEMU 不严格检查 NX,真机 Limine page table 会强制 NX。以下问题只在真机暴露:
|
||||
|
||||
- `rdmsr =A` 内联汇编 bug
|
||||
- 早期未设置 `IA32_GS_BASE` 导致栈保护 prologue 页错误
|
||||
- arena 分配的内存在真机可能不可执行
|
||||
|
||||
真机调试时,`kernel_panic` 应直接通过 COM1 串口输出,不依赖 console/heap。
|
||||
|
||||
---
|
||||
|
||||
## 7. 文档维护规范
|
||||
|
||||
### 7.1 文档分层
|
||||
|
||||
| 层级 | 位置 | 用途 |
|
||||
|------|------|------|
|
||||
| 设计规范 | `RE/` | 完整架构/算法/ABI 规范 |
|
||||
| 模块说明 | `CODE/<module>/README(.md)` | 模块落地说明与实现清单 |
|
||||
| 项目文档 | `docs/` | 架构总览、路线图 |
|
||||
| 项目状态 | `CLAUDE.md` | 当前状态与下一阶段路线 |
|
||||
| 经验记录 | `LESSONS_LEARNED.md` | 每次开发的经验与教训 |
|
||||
|
||||
### 7.2 同步规则
|
||||
|
||||
- 完成阶段性目标后**必须同步** `CLAUDE.md` 路线,避免残留旧状态误导后续开发。
|
||||
- 修改 `RE/` 设计后应同步对应模块 README。
|
||||
- 新增/修改驱动后更新 [CODE/DKM/README.md](CODE/DKM/README.md) 驱动清单。
|
||||
- 架构变更应更新 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)。
|
||||
|
||||
### 7.3 经验记录格式
|
||||
|
||||
每项重要开发应在 [LESSONS_LEARNED.md](LESSONS_LEARNED.md) 追加:
|
||||
|
||||
```markdown
|
||||
## YYYY-MM-DD — <简述>
|
||||
|
||||
### 经验
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
### 教训
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
### 当前已完成 / 下一步计划(可选)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 相关文档
|
||||
|
||||
- [架构设计文档](docs/ARCHITECTURE.md)
|
||||
- [开发路线图](docs/ROADMAP.md)
|
||||
- [CLAUDE.md](CLAUDE.md) — 项目当前状态
|
||||
- [CODE/UTSM/README.md](CODE/UTSM/README.md) — UTSM 模块设计
|
||||
- [CODE/DKM/README.md](CODE/DKM/README.md) — DKM 驱动系统
|
||||
- [LESSONS_LEARNED.md](LESSONS_LEARNED.md) — 开发经验教训
|
||||
@@ -1 +1,53 @@
|
||||
# Deshab-OS
|
||||
# Deshab-OS
|
||||
|
||||
Deshab-OS 是一个从零编写的独立 64 位操作系统,基于 x86_64 long mode,采用单地址空间 Ring0(SAS-R0)内核架构,配套封缄内存(UTSM)、专用恢复根(DRR)与可加载驱动模块系统(DKM)。
|
||||
|
||||
## 项目状态
|
||||
|
||||
当前已完成可启动的实验内核闭环:Limine 引导 → UTSM 首阶段内核 → 14 个 DKM 驱动加载 → DSK 主内核 → 首次启动用户设置向导。
|
||||
|
||||
| 子系统 | 状态 |
|
||||
|--------|------|
|
||||
| 早期启动 / IDT / PIC | ✅ |
|
||||
| UTSM 封缄内存(selftest) | 🔶 |
|
||||
| DKM 驱动系统(14/14 驱动) | ✅ |
|
||||
| DMA 物理页分配器 | ✅ |
|
||||
| AHCI / NVMe 块设备 | 🔶 |
|
||||
| FAT32 只读文件系统 | 🔶 |
|
||||
| e1000 RX/TX 网络 | 🔶 |
|
||||
| 字体系统(DBF,GB2312 全覆盖) | ✅ |
|
||||
| FirstInit 用户设置向导 | 🔶 |
|
||||
| SAS-R0-PCQ 调度器 | ⬜ |
|
||||
| DRR 恢复系统 | ⬜ |
|
||||
|
||||
## 核心架构
|
||||
|
||||
```text
|
||||
SAS-R0-PCQ 单地址空间 Ring0 + Per-CPU O(1) 位图调度器
|
||||
UTSM UUID 调谐封缄内存(所有内存存密文,明文须经 UTRW 读写器)
|
||||
UTRW 带标记读写器(Fast Path / Slow Path)
|
||||
DRR 专用恢复根(看门狗 / checkpoint / A-B 回滚 / 独立 Emergency Pool)
|
||||
DKM 驱动模块系统(ELF64 .drv ABI,4 stage 分阶段加载)
|
||||
```
|
||||
|
||||
## 文档
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [架构设计文档](docs/ARCHITECTURE.md) | 系统整体架构、五大核心子系统、内存模型、驱动系统 |
|
||||
| [启动路线设计](docs/BOOT_SEQUENCE.md) | B0-B4 五阶段启动序列、启动契约、回退链、视觉体验 |
|
||||
| [开发路线图](docs/ROADMAP.md) | 分阶段开发路线、里程碑、验收标准 |
|
||||
| [贡献与协作规范](CONTRIBUTING.md) | 开发环境、代码规范、Git 工作流、PR 流程 |
|
||||
| [CLAUDE.md](CLAUDE.md) | 项目当前状态与下一阶段路线 |
|
||||
| [UTSM 模块设计](CODE/UTSM/README.md) | 封缄内存模块完整设计 |
|
||||
| [DKM 驱动系统](CODE/DKM/README.md) | 驱动模块系统说明 |
|
||||
| [DSK 主内核](CODE/dsk/README) | 主内核说明与 boot context |
|
||||
| [开发经验记录](LESSONS_LEARNED.md) | 开发过程中的经验与教训 |
|
||||
|
||||
## 构建
|
||||
|
||||
```powershell
|
||||
# 需求:LLVM Clang + ld.lld + Python/Pillow + QEMU
|
||||
.\build.bat # 构建 utsm.elf + deshab.elf + 14 个 .drv + ISO/deshab.img
|
||||
.\ISO\run_qemu.bat # QEMU UEFI 启动验证
|
||||
```
|
||||
|
||||
@@ -0,0 +1,499 @@
|
||||
# Deshab-OS 架构设计文档
|
||||
|
||||
> 本文档描述 Deshab-OS 的系统整体架构、核心子系统设计与关键技术约束。
|
||||
> 它是 [UTSM 模块设计](../CODE/UTSM/README.md)、[DKM 驱动系统](../CODE/DKM/README.md)、[DSK 主内核](../CODE/dsk/README) 等模块文档的上层索引与架构总览。
|
||||
|
||||
---
|
||||
|
||||
## 1. 项目定位
|
||||
|
||||
Deshab-OS 是一个**从零编写的独立 64 位操作系统**,不基于 Linux 或任何现有内核。项目目标是在 x86_64 long mode 上构建一个**极高权限、极高效率**的单地址空间 Ring0 内核,并配套完整的驱动加载、文件系统、网络、图形与首次启动体验。
|
||||
|
||||
| 属性 | 说明 |
|
||||
|------|------|
|
||||
| **目标架构** | x86_64 long mode(Higher Half,内核映射于 `0xffffffff80000000` 以上) |
|
||||
| **权限模型** | 单地址空间 Ring0(SAS-R0),不追求传统多用户强隔离 |
|
||||
| **引导器** | Limine(UEFI 优先,BIOS 兼容) |
|
||||
| **主语言** | C11(freestanding)+ x86_64 汇编 |
|
||||
| **工具链** | LLVM Clang + ld.lld(`-mcmodel=kernel -mno-sse -msoft-float`) |
|
||||
| **构建/验证** | PowerShell `build.ps1` → `ISO/deshab.img`(GPT + FAT32 ESP)→ QEMU UEFI |
|
||||
|
||||
### 1.1 设计哲学
|
||||
|
||||
1. **极高权限与极高效率优先**——内核与驱动同处 Ring0,热路径必须保持 O(1)。
|
||||
2. **内存默认封缄**——所有普通内存存密文,明文读写必须经过统一读写器(UTSM/UTRW)。
|
||||
3. **恢复根独立**——DRR 拥有独立紧急内存池,普通 OOM 不阻断 recovery。
|
||||
4. **驱动与内核解耦**——驱动通过稳定 ABI(`dkm_kernel_api`)调用内核服务,不直接依赖任意内核符号。
|
||||
5. **先闭环再扩展**——每个子系统先用最小可验证链路跑通,再逐步深化数据路径。
|
||||
|
||||
---
|
||||
|
||||
## 2. 系统整体架构
|
||||
|
||||
### 2.1 启动链路
|
||||
|
||||
```text
|
||||
UEFI 固件 / BIOS
|
||||
└─ Limine bootloader (BOOTX64.EFI)
|
||||
├─ 读取 limine.conf
|
||||
├─ 加载 boot():/boot/utsm.elf ← 首阶段内核
|
||||
└─ 预加载 boot module:
|
||||
manifest.json / 14 个 *.drv / deshab.elf / test.fat32
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ UTSM 首阶段内核 (utsm.elf) │
|
||||
│ 早期启动 / 封缄内存 / DKM 驱动加载 │
|
||||
│ 平台发现 / DSK 加载与跳转 │
|
||||
└───────────────┬─────────────────────┘
|
||||
│ dsk_boot_context (RDI)
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ DSK 主内核 (deshab.elf) │
|
||||
│ 长期运行期 / 首次启动流程 │
|
||||
│ 系统初始化调度 / 用户设置向导 │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 双阶段内核
|
||||
|
||||
Deshab 采用**双阶段内核**模型,职责严格分层:
|
||||
|
||||
| 阶段 | 产物 | 职责 | 不应做的事 |
|
||||
|------|------|------|-----------|
|
||||
| **UTSM** | `SYSTEM/boot/utsm.elf` | Long mode C 入口、serial、IDT、arena、DMA、UTSM init、DKM 首轮驱动加载、平台发现、DSK ELF 加载与跳转 | 不接管长期调度;不重复 Limine 原始解析 |
|
||||
| **DSK** | `SYSTEM/system/deshab64/deshab.elf` | 接收 boot context、主内核生命周期、首次启动动画、调度 mouseInit/FirstInit/netman、块设备/VFS/网络运行期 | 不重复早期启动职责 |
|
||||
|
||||
UTSM 通过版本化的 `dsk_boot_context` 向 DSK 传递 HHDM、RSDP、framebuffer、boot modules、DKM API/driver table、UTSM/DRR 状态等信息,跳转约定:
|
||||
|
||||
```text
|
||||
RDI = struct dsk_boot_context *
|
||||
RSI = RDX = 0
|
||||
中断状态 = disabled
|
||||
paging = UTSM 当前页表 (higher-half + HHDM)
|
||||
```
|
||||
|
||||
### 2.3 UTSM 启动序列
|
||||
|
||||
源自 [`CODE/UTSM/kernel/main.c`](../CODE/UTSM/kernel/main.c):
|
||||
|
||||
```text
|
||||
kernel_main()
|
||||
→ serial_init() 早期串口(不无限等待 ready 位)
|
||||
→ idt_init() IDT 0–47 + PIC remap 到 0x20–0x2f
|
||||
→ arena_init() 内核 arena(16MB)
|
||||
→ dma_init() 物理页 bitmap 分配器(Limine USABLE → bitmap)
|
||||
→ net_init() netdev registry(8 槽固定表)
|
||||
→ drr_stub_init() DRR 占位
|
||||
→ utsm_init() 封缄内存核心初始化
|
||||
→ dkm_init() + dkm_fill_platform_info()
|
||||
→ dsm_load_by_manifest() 按 manifest.json 分 4 stage 加载 14 个 .drv
|
||||
→ utsm_selftest_run() UTSM/PCKC/UTRW 自检
|
||||
→ dsk_load_and_jump() 加载 deshab.elf(优先 FAT32 block provider,回退 Limine module)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 五大核心架构支柱
|
||||
|
||||
Deshab 的内核架构由五个紧密协作的子系统构成:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Deshab 内核架构"
|
||||
SAS["SAS-R0-PCQ<br/>单地址空间 Ring0<br/>Per-CPU O(1) 位图调度器"]
|
||||
UTSM["UTSM<br/>UUID 调谐封缄内存"]
|
||||
UTRW["UTRW<br/>带标记读写器<br/>Fast / Slow Path"]
|
||||
DRR["DRR<br/>专用恢复根<br/>看门狗 / checkpoint / 回滚"]
|
||||
DKM["DKM<br/>驱动模块系统<br/>ELF64 .drv ABI"]
|
||||
end
|
||||
|
||||
SAS -->|任务携带 crypto 上下文| UTSM
|
||||
UTSM -->|明文访问| UTRW
|
||||
UTRW -->|dirty 标记 / writer_seq| DRR
|
||||
DRR -->|root key / recovery| UTSM
|
||||
DKM -->|驱动内存纳入 UTSM| UTSM
|
||||
DKM -->|故障上报 / recovery ops| DRR
|
||||
SAS -->|任务切换只加载 crypto 指针| UTSM
|
||||
```
|
||||
|
||||
### 3.1 SAS-R0-PCQ — 单地址空间 Ring0 调度模型
|
||||
|
||||
```text
|
||||
SAS-R0 = Single Address Space, Ring 0
|
||||
PCQ = Per-CPU O(1) 位图调度器
|
||||
```
|
||||
|
||||
- **单地址空间**:内核与所有任务共享同一虚拟地址空间,无用户态/内核态隔离。
|
||||
- **Ring0**:所有代码运行在最高特权级,不追求传统多用户强安全隔离。
|
||||
- **Per-CPU 调度**:每个 CPU 维护独立 runqueue,调度热路径 O(1)。
|
||||
- **任务结构**携带 UTSM 加密上下文(`process_uuid`、capability table、`hot_segment_hint`)。
|
||||
|
||||
任务状态机:`READY → RUNNING → BLOCKED / SLEEPING → RECOVERING / FAULTED → ZOMBIE`
|
||||
|
||||
> **设计约束**:调度切换路径中**禁止**扫描 capability table、计算 MAC、写 checkpoint 或重加密整段——这些会破坏 O(1) 目标。切换时只做:标记 PWC dirty flush、保存 hot_segment_hint、设置 PCKC.current_process_uuid、加载 next.crypto。
|
||||
|
||||
### 3.2 UTSM — UUID 调谐封缄内存
|
||||
|
||||
```text
|
||||
UTSM = UUID-Tuned Sealed Memory
|
||||
```
|
||||
|
||||
UTSM 是 Deshab 内存模型的核心:**所有普通内存可以被直接读取,但读到的是密文;真正有效的明文读写必须经过 UTRW 读写器。** UUID 作为进程和内存段的调谐因子,DRR 负责 root key 与恢复。
|
||||
|
||||
**核心规则**:
|
||||
|
||||
1. 数据区只存连续密文,UUID 不插入数据区(避免破坏 cache line / DMA / 批量复制)。
|
||||
2. UUID 使用 128-bit 二进制格式(固定长度、cache 友好、适合 KDF/SIMD)。
|
||||
3. 每个加密段有独立 DMP(段描述符元页)。
|
||||
4. 每个任务有 `process_uuid` 和 capability table。
|
||||
5. 加密粒度:**64B cache line**;Dirty 粒度:**4KB page**;MAC 粒度:**4KB page**。
|
||||
|
||||
**段内存布局**:
|
||||
|
||||
```text
|
||||
+-------------------------------+
|
||||
| DMP: Descriptor Meta Page | ← 热路径加速结构
|
||||
+-------------------------------+
|
||||
| Cipher Data Page 0 |
|
||||
| Cipher Data Page 1 | ← 连续密文
|
||||
| ... |
|
||||
+-------------------------------+
|
||||
```
|
||||
|
||||
**加密方案**(原语待定型,见 [§10 开放设计点](#10-开放设计点)):
|
||||
|
||||
```text
|
||||
segment_key = KDF(DRR_root_key, process_uuid, segment_uuid, key_epoch)
|
||||
tweak_seed = hash(process_uuid, segment_uuid, key_epoch)
|
||||
tweak = hash(tweak_seed, line_index, key_epoch)
|
||||
ciphertext = plaintext XOR stream(segment_key, tweak)
|
||||
plaintext = ciphertext XOR stream(segment_key, tweak)
|
||||
```
|
||||
|
||||
**段状态机**:`FREE → ACTIVE → CHECKPOINTING / SEALED → RECOVERING → POISONED / DESTROYED`
|
||||
|
||||
完整设计见 [CODE/UTSM/README.md](../CODE/UTSM/README.md) 与 [RE/UTSM_设计架构.md](../RE/UTSM_设计架构.md)。
|
||||
|
||||
### 3.3 UTRW — 带标记读写器
|
||||
|
||||
UTRW 是访问 UTSM 明文的**唯一合法路径**,分三层:
|
||||
|
||||
| 层级 | 说明 |
|
||||
|------|------|
|
||||
| **Level 0 — Raw Access** | 直接读 `cipher_base`,得到密文(不可用明文) |
|
||||
| **Level 1 — Fast Path** | capability O(1) 定位段 → PCKC 命中 → 无全局锁、无 trap 解密 |
|
||||
| **Level 2 — Slow Path** | key miss / epoch mismatch / MAC fail / checkpoint 等异常处理 |
|
||||
|
||||
**Fast Path 定位**:`segment_slot + generation + epoch` 三元组直接定位并验证段。
|
||||
|
||||
**Fast Read 用 seqlock**:读 `writer_seq`(before),奇数则重试/slow;读完再读(after),`before != after` 重试。
|
||||
|
||||
**Fast Write**:`writer_seq++` 进奇数写态 → 按 64B line 加密 → 写密文 → 标 dirty bitmap → `writer_seq++` 回偶;强恢复段前后写 `WRITE_INTENT` / `WRITE_COMMIT` log。
|
||||
|
||||
**部分写**必须先解密旧 64B line,合并新明文后重新加密整条 line。
|
||||
|
||||
**Slow Path 错误策略**:
|
||||
|
||||
| 错误 | 处理 |
|
||||
|------|------|
|
||||
| `KEY_MISS` | 派生 key 写 PCKC,回 Fast Path |
|
||||
| `EPOCH_EXPIRED` | 刷新 `cap.epoch` + `auth_tag`,清旧 key |
|
||||
| `MAC_FAILED` | 标 suspicious page + 通知 DRR + 试 page rollback |
|
||||
| `SEGMENT_POISONED` | 交 DRR 决定回滚 / 重建 / kill task |
|
||||
|
||||
### 3.4 DRR — 专用恢复根
|
||||
|
||||
```text
|
||||
DRR = Dedicated Recovery Root
|
||||
```
|
||||
|
||||
DRR 是独立于普通调度器的恢复根,负责看门狗、checkpoint、recovery log、A-B 回滚。
|
||||
|
||||
**核心约束**:
|
||||
|
||||
- DRR 必须拥有**独立 Emergency Pool**,普通 allocator 永远不能分配它;普通系统 OOM ≠ DRR OOM。
|
||||
- recovery 路径**禁止依赖普通堆分配器**。
|
||||
- Emergency Pool 耗尽时直接进入 system rollback。
|
||||
- checkpoint 只处理 dirty shard / dirty page,**不扫描全内存**。
|
||||
|
||||
**Emergency Pool 分配算法**:`class freelist → 切 emergency pages → 不足则写 EXHAUSTED → system rollback`。
|
||||
|
||||
**Checkpoint 类型**:
|
||||
|
||||
| 类型 | 保存内容 |
|
||||
|------|---------|
|
||||
| Light Checkpoint | segment table、DMP、dirty shard summary、writer_seq、key_epoch、MAC root |
|
||||
| Dirty Page Checkpoint | dirty page 密文副本、dirty page MAC、dirty shard、segment descriptor |
|
||||
| Boot Checkpoint | 内核镜像 slot、UTSM root epoch、DRR boot status、启动阶段状态 |
|
||||
|
||||
**A/B 双槽元数据**:当前 active = A → 新 checkpoint 写 B → 写完 metadata + dirty index + MAC root + CRC → flush → 原子切换 active = B → 旧 A 保留为 fallback。恢复时优先读 active slot,CRC 错则 fallback 另一槽,两槽皆坏则 system rollback。
|
||||
|
||||
**回滚级别**:Page Rollback(单页)→ Segment Rollback(整段)→ System Rollback(控制面严重损坏,reboot 切 last_good_slot)。
|
||||
|
||||
**Dirty Shard 优化**:将大 dirty bitmap 拆成多个 shard,每个 shard 管理一段连续页范围并维护 `dirty_count`。checkpoint 跳过 `dirty_count == 0` 的 shard,复杂度从"扫描全 bitmap"优化为 `O(dirty_shards + dirty_pages)`。
|
||||
|
||||
### 3.5 DKM — 驱动模块系统
|
||||
|
||||
```text
|
||||
DKM = Deshab Kernel Module
|
||||
DSM = Driver Startup Manager
|
||||
```
|
||||
|
||||
DKM 负责在内核启动时从 `SYSTEM/driver/manifest.json` 读取清单,按 stage 分阶段加载 ELF64 `.drv` 驱动模块。
|
||||
|
||||
**分阶段加载**:
|
||||
|
||||
| Stage | 名称 | 驱动 | 失败策略 |
|
||||
|-------|------|------|---------|
|
||||
| 0 | platform | timer / apic / acpi / pci | required 失败 → DRR recovery 或 panic |
|
||||
| 1 | boot | console_fb / ahci / nvme / bootfs | required 失败 → DRR recovery |
|
||||
| 2 | filesystem | vfs / fat32 / devfs | required 失败 → fallback bootfs / 只读 |
|
||||
| 3 | optional | e1000 / virtio_net / ps2kbd | 失败只标记 FAILED,继续启动 |
|
||||
|
||||
**驱动 ABI**:每个 `.drv` 必须导出三个符号:
|
||||
|
||||
```c
|
||||
// 描述符(magic=0x444B4D31 "DKM1", abi_version=1)
|
||||
struct dkm_driver_desc *driver_desc;
|
||||
|
||||
// 入口:返回 0 成功,负数失败
|
||||
int driver_init(const struct dkm_kernel_api *api, struct dkm_driver_handle *handle);
|
||||
int driver_exit(struct dkm_driver_handle *handle);
|
||||
```
|
||||
|
||||
**kernel_api 服务接口**——驱动默认通过 `dkm_kernel_api` 调用内核服务,不直接依赖内核符号:
|
||||
|
||||
```text
|
||||
log / mem / utsm / irq / pci / dma / vfs / net / timer / drr
|
||||
+ 平台直通:rsdp_address / fb_* / boot_modules_response / irq_register / hhdm_offset
|
||||
+ block provider registry(驱动向 kernel_api.block 注册块设备)
|
||||
```
|
||||
|
||||
**ELF Loader**:第一版支持 `R_X86_64_64 / RELATIVE / GLOB_DAT / JUMP_SLOT`(必须)、`PC32 / PLT32 / 32 / 32S`(建议);禁止 TLS / IFUNC / lazy binding / 外部动态库 / 用户态 libc。
|
||||
|
||||
**加载状态机**:`DISCOVERED → QUEUED → DEP_WAIT → LOADING → ELF_CHECKED → MEMORY_ALLOCATED → RELOCATED → ABI_CHECKED → INITING → ACTIVE`,失败进入 `FAILED_*` 状态。
|
||||
|
||||
**boot module 查找**(stage0/stage1 不依赖 VFS):path 在 boot module table → 直接内存加载;否则 VFS 可用则从 SYSTEM/path 加载;否则 `BOOT_MODULE_NOT_FOUND`。
|
||||
|
||||
完整设计见 [CODE/DKM/README.md](../CODE/DKM/README.md) 与 [RE/驱动模块ABI设计.md](../RE/驱动模块ABI设计.md)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 辅助数据结构
|
||||
|
||||
### 4.1 DMP — 段描述符元页
|
||||
|
||||
DMP 是热路径加速结构,替代"UUID 数字位置表",提供 O(1) 段定位、快速边界检查、tweak 生成、dirty bitmap / MAC table 定位。每个加密段有独立 DMP,含 `fast_base / fast_limit / fast_tweak_seed / fast_key_epoch` 等字段 + CRC 校验。
|
||||
|
||||
### 4.2 PCKC — 每 CPU 密钥缓存
|
||||
|
||||
```text
|
||||
PCKC = Per-CPU Key Cache
|
||||
```
|
||||
|
||||
每 CPU 一个 PCKC,默认 8 槽(高并发可扩 16),缓存 hot segment 的 key schedule。调度切换时只加载 `next.crypto` 指针和 `hot_segment_hint`,**不扫描 capability table、不刷新全部 key**。替换策略:LRU 或最冷 slot。
|
||||
|
||||
### 4.3 Capability — 段访问凭证
|
||||
|
||||
任务访问段使用 capability(非裸 UUID),热路径通过 `segment_slot + generation + epoch` 直接定位并验证。权限:`READ / WRITE / EXEC / SHARE / DMA`。任务默认 capability:`cap[0]=stack(RW) / cap[1]=heap(RW) / cap[2]=ipc(RWS,可选) / cap[3]=code(RX,可选)`。
|
||||
|
||||
---
|
||||
|
||||
## 5. 内存管理
|
||||
|
||||
### 5.1 当前实现
|
||||
|
||||
| 组件 | 实现 | 位置 |
|
||||
|------|------|------|
|
||||
| **内核 arena** | 16MB bump 分配区,用于 DKM 驱动加载 | `CODE/UTSM/mm/arena.c` |
|
||||
| **DMA 分配器** | Limine USABLE → 物理页 bitmap,返回 `virt = hhdm + phys`,低 4G 钳位 | `CODE/UTSM/mm/dma.c` |
|
||||
| **UTSM 段分配** | DMP + 密文数据区,纳入封缄内存 | `CODE/UTSM/core/segment.c` |
|
||||
|
||||
### 5.2 内存布局(全局区域)
|
||||
|
||||
```text
|
||||
+--------------------------------------------------+
|
||||
| Normal Encrypted Segment Region 普通加密段数据区 |
|
||||
+--------------------------------------------------+
|
||||
| DMP Pool 段描述符元页池 |
|
||||
+--------------------------------------------------+
|
||||
| Segment Table 全局段表 |
|
||||
+--------------------------------------------------+
|
||||
| PCKC Area 每 CPU 密钥缓存区 |
|
||||
+--------------------------------------------------+
|
||||
| DRR Reserved Region root key / checkpoint / recovery log |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
### 5.3 关键约束
|
||||
|
||||
- **DMA 缓冲必须来自明确物理页分配**,不能用内核高半虚拟地址(BSS)反推物理地址——否则物理页与 CPU 映射不保证一致(e1000 DMA 卡死的根因)。
|
||||
- **低 4G 约束**:32 位 BAR 设备(e1000 等)的 DMA 描述符/缓冲需落在低 4G。
|
||||
- DATA/BSS 段使用 `PF_R|PF_W|PF_X`(SAS-R0 下驱动模块内存需可执行)。
|
||||
- 未启用 FPU/SSE 前编译必须 `-mno-sse -mno-sse2 -mno-mmx -msoft-float`。
|
||||
|
||||
---
|
||||
|
||||
## 6. 驱动子系统现状
|
||||
|
||||
当前 14/14 DKM 驱动已完成 discovery 与加载闭环:
|
||||
|
||||
| Stage | 驱动 | 实现进度 |
|
||||
|-------|------|---------|
|
||||
| 0 | **timer** | PIT 校准,100ms busy-wait demo |
|
||||
| 0 | **apic** | CPUID/MADT/LAPIC MMIO 只读探测,保留 PIC IRQ 路由 |
|
||||
| 0 | **acpi** | RSDP → XSDT,ACPI 表枚举 |
|
||||
| 0 | **pci** | PCI config space 扫描,设备枚举 |
|
||||
| 1 | **console_fb** | Limine framebuffer,淡蓝背景 + 四色圆弧加载环(纯整数运算) |
|
||||
| 1 | **ahci** | PCI AHCI 探测 + ABAR HHDM 映射 + SATA IDENTIFY/READ DMA + 注册 `ahci0` block provider |
|
||||
| 1 | **nvme** | PCI NVMe 探测(BAR0 位于 4G 以上,等待高位 MMIO 映射) |
|
||||
| 1 | **bootfs** | Limine boot module 内存文件系统 |
|
||||
| 2 | **vfs** | 挂载 bootfs,文件查找/读取 |
|
||||
| 2 | **fat32** | 只读 FAT32,优先 block provider,回退 boot module |
|
||||
| 2 | **devfs** | `/dev/version` `/dev/platform` `/dev/fb0` `/dev/modules` `/dev/boot/` |
|
||||
| 3 | **ps2kbd** | PS/2 IRQ1,scan code set 1 → ASCII |
|
||||
| 3 | **e1000** | PCI 探测 + MAC + IRQ + **完整 RX/TX ring**(物理页 bitmap 根治 DMA) |
|
||||
| 3 | **virtio_net** | PCI 探测 + modern virtio capability 枚举(未做 feature negotiation / virtqueue) |
|
||||
|
||||
---
|
||||
|
||||
## 7. 文件系统与块设备
|
||||
|
||||
### 7.1 块设备 provider registry
|
||||
|
||||
UTSM 通过 `kernel_api.block` 提供块设备注册与读取接口,解耦驱动与文件系统:AHCI 注册 `ahci0` 并实现 LBA read,FAT32 不需知道 AHCI 细节。block read 内部按最多 8 扇区分块(AHCI 当前单 PRDT entry)。
|
||||
|
||||
### 7.2 FAT32
|
||||
|
||||
- 只读 BPB/FAT/目录项解析,优先通过 block provider 读取,无设备或 BPB 无效时回退 boot module。
|
||||
- DSK loader 内嵌 FAT32 解析器,优先 `kernel_api.block` + FAT32 读取 `deshab.elf`,无块设备时回退 Limine module。
|
||||
|
||||
### 7.3 devfs
|
||||
|
||||
暴露 `/dev/version`、`/dev/platform`、`/dev/fb0`、`/dev/modules`、`/dev/boot/`。
|
||||
|
||||
---
|
||||
|
||||
## 8. 网络子系统
|
||||
|
||||
### 8.1 netdev registry
|
||||
|
||||
早期固定 8 槽 netdev registry,O(1) 注册与查询。discovery-only 驱动也能注册 name/MAC/flags。
|
||||
|
||||
### 8.2 net API 边界
|
||||
|
||||
`kernel_api.net` 收窄为 `dkm_net_api*`:`register_netdev / submit_tx / poll_rx`(第一版只定边界)。
|
||||
|
||||
### 8.3 netman 网络管理器
|
||||
|
||||
`netman.elf` 由 DSK 调度,负责配置解析(`conf.conf` / root 8.3 `NETCONF.CNF`)、netdev 枚举、状态输出。在 e1000/virtio-net 仍缺完整数据路径时先做配置管理闭环。
|
||||
|
||||
---
|
||||
|
||||
## 9. 图形、字体与首次启动
|
||||
|
||||
### 9.1 字体系统
|
||||
|
||||
自研 **DBF(Deshab Bitmap Font)** 格式,8bpp 灰度:
|
||||
|
||||
| 文件 | 精度 | 覆盖 |
|
||||
|------|------|------|
|
||||
| `simhei_16.dbf` | 16×16 | GB2312 全部 6763 汉字 + ASCII 32–126 |
|
||||
| `simhei_24.dbf` | 24×24 | 同上 |
|
||||
| `simhei_32.dbf` | 32×32 | 同上 |
|
||||
|
||||
- 索引按 codepoint 升序,二分查找。
|
||||
- 生成工具:`CODE/font/mkfont.py`(Python + Pillow)。
|
||||
- FirstInit 使用 `render_embedded.py` 预渲染中文位图嵌入 ELF,避免运行时 TTF 解析。
|
||||
|
||||
### 9.2 首次启动流程
|
||||
|
||||
```text
|
||||
DSK 启动
|
||||
→ 旋转加载动画(双缓冲精灵、顺时针、comet-tail 渐变弧)
|
||||
→ FAT32 读取 firstInit.txt
|
||||
→ firstInit == 0(首次启动):
|
||||
DSK → mouseInit.elf(PS/2 鼠标安全 stub)→ 返回 DSK
|
||||
DSK → FirstInit.elf
|
||||
→ 环淡出 → "欢迎使用 Deshab" → 设置提示
|
||||
→ 账户设置卡片(圆角矩形、白色输入框、18px 中文)
|
||||
→ 键盘输入:计算机名 / 用户名 / 密码
|
||||
→ SHA256 密码摘要 + XOR 加密配置缓冲
|
||||
→ "设置完成"
|
||||
→ firstInit != 0:正常启动(待实现)
|
||||
```
|
||||
|
||||
| 组件 | 产物 | 职责 |
|
||||
|------|------|------|
|
||||
| **FirstInit** | `SYSTEM/system/user/use/FirstInit.elf` | 用户设置向导(计算机名/用户名/密码/网络配置) |
|
||||
| **mouseInit** | `SYSTEM/system/deshab64/mouse/mouseInit.elf` | PS/2 鼠标安全初始化 stub |
|
||||
| **netman** | `SYSTEM/system/deshab64/network/netman.elf` | 网络配置加载与 netdev 枚举 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 开放设计点
|
||||
|
||||
以下为当前架构中**尚未定型**的设计决策,需在后续阶段明确:
|
||||
|
||||
1. **加密原语未指定**——KDF / hash / stream cipher / MAC 的具体算法(HKDF? BLAKE2? AES-CTR? Poly1305? CMAC?)三份设计文档均未确定。当前 UTSM selftest 使用占位 XOR stream,保留 64B line 接口以便后续替换。
|
||||
2. **kernel_api 设计态 vs 实现态**——RE 设计文档定义全部 typed sub-struct 指针(`dkm_log_api*` 等 10 个),当前实现为 `const void *` 占位 + Limine 字段直通。需规划迁移路径。
|
||||
3. **block 未作为独立子 API**——block 走 provider 注册(如 ahci 向 `kernel_api.block` 注册),而非 typed sub-struct。
|
||||
4. **log API 签名分歧**——RE 设计为 printf 变参 `void (*info)(const char *fmt, ...)`,当前实现为 `void (*info)(const char *msg)`。
|
||||
5. **v1 不追求**——完整 RAM 原地回滚、对恶意 Ring0 代码的强安全隔离、设备外部副作用回滚。设备恢复依赖文件系统 journal;网卡 TX 已发包不回滚。
|
||||
|
||||
---
|
||||
|
||||
## 11. 系统目录约定
|
||||
|
||||
```text
|
||||
SYSTEM/ # 打包为 IMG 后的系统根目录
|
||||
├── boot/
|
||||
│ ├── utsm.elf # 首阶段内核(Limine 直接加载)
|
||||
│ └── limine.conf # 引导配置(预加载所有 boot module)
|
||||
├── driver/
|
||||
│ ├── manifest.json # 驱动加载清单
|
||||
│ ├── platform/ bus/ block/ # *.drv 驱动模块
|
||||
│ ├── fs/ net/ input/ console/
|
||||
│ └── test.fat32 # FAT32 驱动测试镜像
|
||||
├── system/
|
||||
│ ├── deshab64/
|
||||
│ │ ├── deshab.elf # DSK 主内核
|
||||
│ │ ├── mouse/mouseInit.elf
|
||||
│ │ └── network/netman.elf
|
||||
│ ├── font/ # simhei*.dbf 字体
|
||||
│ └── user/use/ # FirstInit.elf + firstInit.txt
|
||||
└── EFI/BOOT/BOOTX64.EFI # UEFI 引导
|
||||
|
||||
CODE/ # 源码
|
||||
├── UTSM/ # 首阶段内核源码
|
||||
├── dsk/ # DSK 主内核源码
|
||||
├── DKM/ # 14 个驱动源码
|
||||
├── firstInit/ mouse/ netman/ # 用户空间初始化程序
|
||||
└── font/ # 字体工具
|
||||
|
||||
RE/ # 研究与设计文档
|
||||
├── UTSM_设计架构.md
|
||||
├── UTSM_算法记录.md
|
||||
└── 驱动模块ABI设计.md
|
||||
|
||||
docs/ # 项目文档(本文档所在)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 相关文档索引
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [CODE/UTSM/README.md](../CODE/UTSM/README.md) | UTSM 封缄内存模块完整设计 |
|
||||
| [CODE/DKM/README.md](../CODE/DKM/README.md) | DKM 驱动模块系统说明 |
|
||||
| [CODE/dsk/README](../CODE/dsk/README) | DSK 主内核说明与 boot context |
|
||||
| [RE/UTSM_设计架构.md](../RE/UTSM_设计架构.md) | UTSM 架构记录 |
|
||||
| [RE/UTSM_算法记录.md](../RE/UTSM_算法记录.md) | UTSM 核心算法记录 |
|
||||
| [RE/驱动模块ABI设计.md](../RE/驱动模块ABI设计.md) | DKM ABI 详细设计 |
|
||||
| [LESSONS_LEARNED.md](../LESSONS_LEARNED.md) | 开发经验与教训记录 |
|
||||
| [CLAUDE.md](../CLAUDE.md) | 项目上下文与当前状态 |
|
||||
| [docs/BOOT_SEQUENCE.md](./BOOT_SEQUENCE.md) | 启动路线设计(B0-B4 五阶段) |
|
||||
| [docs/ROADMAP.md](./ROADMAP.md) | 开发路线图 |
|
||||
| [CONTRIBUTING.md](../CONTRIBUTING.md) | 贡献与协作规范 |
|
||||
@@ -0,0 +1,596 @@
|
||||
# Deshab 启动路线设计
|
||||
|
||||
> 本文档定义 Deshab-OS 从上电到用户可交互的完整启动序列。
|
||||
> 它是 [架构设计文档](./ARCHITECTURE.md) 中启动链路的深度展开,基于真实源码实现。
|
||||
|
||||
---
|
||||
|
||||
## 0. 设计理念
|
||||
|
||||
Deshab 的启动不是一条简单的"引导→内核"直线,而是一个**带契约的分阶段唤醒过程**。每个阶段都有明确的入口条件、出口契约和失败语义,失败时可沿**启动回退链**降级到上一个稳定点,而非直接 panic。
|
||||
|
||||
### 0.1 原创命名体系
|
||||
|
||||
延续 Deshab 的工程化缩写风格(SAS-R0-PCQ / UTSM / DRR / DKM),启动序列命名为 **DBS(Deshab Boot Sequence)**,划分为五个阶段:
|
||||
|
||||
| 阶段 | 代号 | 名称 | 含义 | 产物 |
|
||||
|------|------|------|------|------|
|
||||
| B0 | **Ignis** | 火种 | 固件点燃,引导器接管 | `utsm.elf` 入内存 |
|
||||
| B1 | **Sigillum** | 封缄解封 | UTSM 首阶段内核建立封缄内存与驱动底座 | 14 个 DKM 驱动 ACTIVE |
|
||||
| B2 | **Transitus** | 交接 | UTSM 向 DSK 版本化传递控制权 | `dsk_boot_context` 就绪 |
|
||||
| B3 | **Origo** | 溯源 | DSK 判定首次/正常启动,调度系统初始化器 | `firstInit` 标志判定 |
|
||||
| B4 | **Excitas** | 唤醒 | 用户设置向导或正常启动路径 | 用户可交互 |
|
||||
|
||||
> 命名取自拉丁语,呼应 Deshab "封缄内存"(Sealed Memory)的意象:系统从封缄中逐层苏醒。
|
||||
|
||||
### 0.2 三个核心概念
|
||||
|
||||
**启动契约(Boot Contract)**——每个阶段 B(n) 对下一阶段 B(n+1) 做出明确承诺。契约包含:
|
||||
- **Entry**:进入本阶段时 CPU/内存/设备必须处于什么状态
|
||||
- **Exit**:离开本阶段时必须完成什么、向下一阶段传递什么
|
||||
- **Fail**:本阶段失败时的降级策略(回退 / DRR 接管 / panic)
|
||||
|
||||
**启动锚点(Boot Anchor)**——每个阶段结束时的可验证检查点,输出稳定的串口日志标记。锚点是"已知稳定点",回退只能退到锚点,不能退到阶段中间。例如 `[UTSM] SELFTEST PASS` 是 B1 的锚点。
|
||||
|
||||
**启动回退链(Boot Fallback Chain)**——失败时的降级路径,每级回退对应一个锚点:
|
||||
|
||||
```text
|
||||
B2 DSK 块设备加载失败
|
||||
└─ 回退 B1 锚点:改用 Limine boot module 加载 deshab.elf
|
||||
B1 某驱动 init 失败
|
||||
├─ required 驱动 → DRR recovery 或 panic
|
||||
└─ optional 驱动 → 标记 FAILED,继续启动
|
||||
B0 BCB 校验失败
|
||||
└─ 切换 last_good_slot(未来 DRR 实现)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. 启动总览
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
PWR["上电 Power-on"] --> B0
|
||||
subgraph B0["B0 Ignis 火种"]
|
||||
B0A["UEFI/BIOS 固件"] --> B0B["Limine bootloader<br/>读 limine.conf"]
|
||||
B0B --> B0C["加载 utsm.elf<br/>预加载 17 个 boot module"]
|
||||
end
|
||||
B0 --> B1
|
||||
subgraph B1["B1 Sigillum 封缄解封"]
|
||||
B1A["早期启动<br/>serial/IDT/arena/DMA"] --> B1B["UTSM init<br/>封缄内存+PCKC"]
|
||||
B1B --> B1C["DKM 4-stage<br/>14 驱动加载"] --> B1D["selftest 锚点"]
|
||||
end
|
||||
B1 --> B2
|
||||
subgraph B2["B2 Transitus 交接"]
|
||||
B2A["FAT32 block provider<br/>读取 deshab.elf"] -.失败.-> B2F["回退 Limine module"]
|
||||
B2F --> B2B
|
||||
B2A --> B2B["ELF 校验+PT_LOAD"]
|
||||
B2B --> B2C["填充 dsk_boot_context<br/>跳转 DSK"]
|
||||
end
|
||||
B2 --> B3
|
||||
subgraph B3["B3 Origo 溯源"]
|
||||
B3A["渐变背景+旋转环"] --> B3B["FAT32 读 firstInit.txt"]
|
||||
B3B --> B3C{"firstInit==0?"}
|
||||
end
|
||||
B3 -->|首次| B4F
|
||||
B3 -->|正常| B4N
|
||||
subgraph B4F["B4 Excitas 唤醒(首次)"]
|
||||
B4F1["mouseInit"] --> B4F2["netman"] --> B4F3["FirstInit 向导"]
|
||||
end
|
||||
subgraph B4N["B4 Excitas 唤醒(正常)"]
|
||||
B4N1["正常启动路径<br/>待实现"]
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. B0 Ignis — 火种
|
||||
|
||||
### 2.1 契约
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **Entry** | CPU 上电,执行固件(UEFI 优先),内存可用,PCI 设备已枚举 |
|
||||
| **Exit** | `utsm.elf` 已加载到内存,boot module table 已构建,`limine.conf` 已解析,控制权交给 `_start` |
|
||||
| **Fail** | 固件失败 → 硬件级复位;Limine 找不到 `utsm.elf` → 引导失败停在固件错误界面 |
|
||||
|
||||
### 2.2 执行细节
|
||||
|
||||
**固件阶段**:UEFI 固件加载 `SYSTEM/EFI/BOOT/BOOTX64.EFI`(即 Limine)。QEMU 场景需显式指定 UEFI 固件(`edk2-x86_64-code.fd` / `OVMF_CODE.fd`)。
|
||||
|
||||
**Limine 阶段**(源自 [`SYSTEM/boot/limine.conf`](../SYSTEM/boot/limine.conf)):
|
||||
|
||||
```text
|
||||
timeout: 0
|
||||
serial: yes
|
||||
verbose: yes
|
||||
|
||||
/UTSM boot
|
||||
protocol: limine
|
||||
kernel_path: boot():/boot/utsm.elf
|
||||
module_path: boot():/driver/manifest.json # dkm:manifest
|
||||
module_path: boot():/driver/platform/timer.drv # 14 个 .drv
|
||||
... (apic/acpi/pci/console_fb/ahci/nvme/bootfs/vfs/fat32/devfs/e1000/virtio_net/ps2kbd)
|
||||
module_path: boot():/system/deshab64/deshab.elf # dsk:main
|
||||
module_path: boot():/driver/test.fat32 # dkm:test_fat32
|
||||
```
|
||||
|
||||
Limine 从 FAT32 ESP 读取 `utsm.elf` 作为内核,并预加载 **17 个 boot module**:1 个 manifest + 14 个 `.drv` + 1 个 `deshab.elf` + 1 个 `test.fat32`。这些 module 通过 Limine module response 暴露给内核。
|
||||
|
||||
### 2.3 未来扩展(DRR 接入后)
|
||||
|
||||
B0 未来将引入 **BCB(Boot Control Block)** 校验:
|
||||
|
||||
```text
|
||||
1. 读取 Boot Control Block
|
||||
2. 校验 BCB CRC
|
||||
3. 选择 active_slot
|
||||
4. 若 active_slot 失败次数超限 → 切换 last_good_slot
|
||||
5. 加载对应 slot 的 utsm.elf
|
||||
6. 传入 memory map、BCB 地址、DRR reserved region 信息
|
||||
```
|
||||
|
||||
当前 BCB 尚未实现,B0 直接加载单一 `utsm.elf`。
|
||||
|
||||
### 2.4 B0 锚点
|
||||
|
||||
无串口输出(serial 尚未初始化)。锚点为 Limine 成功跳转到 `_start`,由 B1 的 `[UTSM] boot` 间接验证。
|
||||
|
||||
---
|
||||
|
||||
## 3. B1 Sigillum — 封缄解封
|
||||
|
||||
### 3.1 契约
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **Entry** | Long mode 已启用,`_start` 获得控制,RDI/RSI 含 Limine bootloader 信息,中断禁用 |
|
||||
| **Exit** | UTSM 封缄内存初始化完成,14 个 DKM 驱动 ACTIVE,selftest 通过,平台发现完成 |
|
||||
| **Fail** | required 驱动失败 → DRR recovery 或 panic;optional 驱动失败 → 标记 FAILED 继续 |
|
||||
|
||||
### 3.2 入口约定(源自 [`boot.S`](../CODE/UTSM/arch/x86_64/boot.S))
|
||||
|
||||
```asm
|
||||
_start:
|
||||
cli # 进入 C 前必须关中断(IDT 未建)
|
||||
cld # 清方向标志(避免 rep movs 反向)
|
||||
lea kernel_stack_top(%rip), %rsp
|
||||
andq $-16, %rsp # 16 字节栈对齐
|
||||
call kernel_main
|
||||
```
|
||||
|
||||
**强制约束**:
|
||||
1. `cli` / `cld` 必须在最前——未建 IDT 前被中断或方向标志异常会导致三重故障。
|
||||
2. 早期设置 `IA32_GS_BASE`——防止栈保护 prologue 访问 GS 段时页错误(真机三重故障的根因之一)。
|
||||
3. 未启用 FPU/SSE 前编译必须 `-mno-sse -mno-sse2 -mno-mmx -msoft-float`——Clang 在 freestanding 下也可能生成 `xorps/movups`。
|
||||
|
||||
### 3.3 执行序列(源自 [`kernel/main.c`](../CODE/UTSM/kernel/main.c))
|
||||
|
||||
```text
|
||||
kernel_main()
|
||||
① serial_init() 早期串口(不无限等待 ready 位,超时降级)
|
||||
② idt_init() IDT 0–47 stub + PIC remap 到 0x20–0x2f
|
||||
③ arena_init() 内核 arena(16MB bump 分配区)
|
||||
④ dma_init() 物理页 bitmap(Limine USABLE → bitmap,低 4G 钳位)
|
||||
⑤ net_init() netdev registry(8 槽固定表)
|
||||
⑥ drr_stub_init() DRR 占位(真实 DRR 待实现)
|
||||
⑦ utsm_init() 封缄内存:segment table + PCKC
|
||||
⑧ dkm_init() + dkm_fill_platform_info()
|
||||
⑨ dsm_load_by_manifest() 按 manifest.json 分 4 stage 加载 14 个 .drv
|
||||
⑩ utsm_selftest_run() UTSM/PCKC/UTRW 自检
|
||||
⑪ dsk_load_and_jump() → 进入 B2
|
||||
```
|
||||
|
||||
### 3.4 DKM 分阶段加载(源自 [`manifest.json`](../SYSTEM/driver/manifest.json))
|
||||
|
||||
| Stage | 名称 | 驱动 | 失败策略 |
|
||||
|-------|------|------|---------|
|
||||
| 0 | platform | timer → apic → acpi → pci | required 失败 → DRR recovery / panic |
|
||||
| 1 | boot | console_fb / ahci / nvme / bootfs | required 失败 → DRR recovery |
|
||||
| 2 | filesystem | vfs → fat32 / devfs | required 失败 → fallback bootfs / 只读 |
|
||||
| 3 | optional | e1000 / virtio_net / ps2kbd | 失败只标记 FAILED,继续启动 |
|
||||
|
||||
**加载状态机**:`DISCOVERED → QUEUED → DEP_WAIT → LOADING → ELF_CHECKED → MEMORY_ALLOCATED → RELOCATED → ABI_CHECKED → INITING → ACTIVE`
|
||||
|
||||
**ELF 重定位**:必须 `R_X86_64_64/RELATIVE/GLOB_DAT/JUMP_SLOT`,建议 `PC32/PLT32/32/32S`,禁止 TLS/IFUNC/lazy binding。
|
||||
|
||||
**boot module 查找**(stage0/stage1 不依赖 VFS):path 在 boot module table → 内存加载;否则 VFS 可用则从 SYSTEM/path 加载;否则 `BOOT_MODULE_NOT_FOUND`。
|
||||
|
||||
### 3.5 kernel_api 平台直通
|
||||
|
||||
B1 完成后,`dkm_kernel_api` 已暴露:`log / rsdp_address / fb_* / boot_modules_response / irq_register / hhdm_offset / dma.alloc_pages / block / net`。
|
||||
|
||||
### 3.6 B1 锚点
|
||||
|
||||
```text
|
||||
[UTSM] boot
|
||||
... (各初始化阶段日志)
|
||||
[UTSM] SELFTEST PASS ← B1 锚点(稳定点 1)
|
||||
```
|
||||
|
||||
**锚点语义**:到达此日志表示封缄内存、DKM 驱动、平台发现全部就绪,可安全进入 B2。若未到达此锚点,DRR(未来)应能从 B0 重新引导。
|
||||
|
||||
---
|
||||
|
||||
## 4. B2 Transitus — 交接
|
||||
|
||||
### 4.1 契约
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **Entry** | B1 锚点达成,`dkm_kernel_api` 就绪,boot module response 可用 |
|
||||
| **Exit** | `deshab.elf` 已加载并重定位,`dsk_boot_context` 已填充,控制权交给 `dsk_entry(ctx)` |
|
||||
| **Fail** | FAT32 block provider 失败 → 回退 Limine module;两者皆失败 → panic |
|
||||
|
||||
### 4.2 两阶段 DSK 加载(源自 [`dsk_loader.c`](../CODE/UTSM/kernel/dsk_loader.c))
|
||||
|
||||
```text
|
||||
dsk_load_and_jump()
|
||||
① 优先:FAT32 block provider
|
||||
kernel_api.block.read(0, lba, count, buf)
|
||||
→ 解析 BPB → 遍历 root cluster → 找 "DESHAB ELF"
|
||||
→ 沿 FAT 链读取文件到 arena
|
||||
② 回退:Limine boot module
|
||||
遍历 module response 找 path=="/system/deshab64/deshab.elf"
|
||||
或 cmdline=="dsk:main"
|
||||
③ ELF 校验:ELFCLASS64 / ELFDATA2LSB / EM_X86_64 / ET_DYN|ET_EXEC
|
||||
④ PT_LOAD 加载:计算 min/max vaddr → arena 分配 → 清零 → 复制 filesz
|
||||
⑤ 填充 dsk_boot_context
|
||||
⑥ 跳转 entry(ctx)
|
||||
```
|
||||
|
||||
**关键约束**:
|
||||
- `data_start_sec = rsvd + fat_count * spf`——漏掉第二份 FAT 会导致 root cluster 错位。
|
||||
- arena 容量需足够(已从 4MB 扩到 16MB,后续应迁移到物理页分配器)。
|
||||
- 批量读 256 扇区稳定,单扇区连续读偶尔超时——DSK loader 全部用 cluster 级批量读取。
|
||||
|
||||
### 4.3 dsk_boot_context 版本化传递
|
||||
|
||||
源自 [`dsk.h`](../CODE/UTSM/include/utsm/dsk.h),magic = `0x44534B31424F4F54`("DSK1BOOT"):
|
||||
|
||||
```c
|
||||
struct dsk_boot_context {
|
||||
u64 magic; // DSK_BOOT_MAGIC,DSK 入口必须校验
|
||||
u32 abi_version; // DSK_BOOT_ABI_VERSION = 1
|
||||
u32 size;
|
||||
u64 flags; // FROM_UTSM | DKM_READY | FAT32_PATH
|
||||
u64 hhdm_offset; // physical → virtual direct map
|
||||
u64 rsdp_address; // ACPI RSDP
|
||||
u64 framebuffer_address/width/height/pitch/bpp;
|
||||
u64 boot_modules_response;
|
||||
u64 dkm_kernel_api; // DSK 通过此指针访问所有内核服务
|
||||
u64 dkm_driver_table / driver_count;
|
||||
u64 utsm_state / drr_state; // 当前为占位
|
||||
u64 memory_map / count / entry_size;
|
||||
u64 kernel_stack_top;
|
||||
u64 reserved[8]; // 未来扩展(只能追加,不能插入)
|
||||
};
|
||||
```
|
||||
|
||||
**跳转约定**:
|
||||
|
||||
```text
|
||||
RDI = dsk_boot_context *
|
||||
RSI = RDX = 0
|
||||
中断状态 = disabled
|
||||
paging = UTSM 当前页表(higher-half + HHDM)
|
||||
```
|
||||
|
||||
> **ABI 约束**:`dsk_boot_context` 字段只能追加到 `reserved` 区,不能在中间插入,否则 DSK 入口偏移错位。DSK 通过硬偏移读取 `block_read`(`api + 0xA8`),偏移错误会导致 NULL 解引用。
|
||||
|
||||
### 4.4 B2 锚点
|
||||
|
||||
```text
|
||||
[UTSM] loading DSK
|
||||
[UTSM] DSK loaded from FAT32 block provider ← 或 "trying Limine module"
|
||||
[UTSM] DSK image base=0x...
|
||||
[UTSM] DSK entry=0x...
|
||||
[UTSM] jumping to DSK
|
||||
[DSK] boot ← B2 锚点(稳定点 2)
|
||||
[DSK] context ok
|
||||
```
|
||||
|
||||
**锚点语义**:`[DSK] context ok` 表示 magic 校验通过,DSK 已接管控制权。若 `[DSK] bad context` 则 magic 不匹配,DSK 直接 halt。
|
||||
|
||||
---
|
||||
|
||||
## 5. B3 Origo — 溯源
|
||||
|
||||
### 5.1 契约
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **Entry** | B2 锚点达成,`dsk_boot_context` 校验通过,framebuffer 可用 |
|
||||
| **Exit** | `firstInit` 标志已判定,系统初始化器已调度(首次启动时) |
|
||||
| **Fail** | 无 block device → 跳过 firstInit 检查,进入正常启动;FAT32 读取失败 → 视为首次启动 |
|
||||
|
||||
### 5.2 执行序列(源自 [`dsk/main.c`](../CODE/dsk/main.c))
|
||||
|
||||
```text
|
||||
dsk_entry(ctx)
|
||||
① cli # 禁用 IRQ——ps2kbd/IRQ1 和 mouse/IRQ12 handler 在 spinner 期间会崩
|
||||
② 校验 ctx->magic == DSK_BOOT_MAGIC,失败则 halt
|
||||
③ 从 ctx->dkm_kernel_api + 0xA8 取 block_read 函数指针
|
||||
④ 绘制渐变背景(BG_TOP 淡蓝 → BG_BOTTOM 深紫,按 y 插值)
|
||||
⑤ 旋转加载环动画循环:
|
||||
- 双缓冲精灵(128×128 离屏 sprite)
|
||||
- 四色圆弧(顺时针旋转,comet-tail 渐变)
|
||||
- 每帧按行重算 sprite 背景以匹配渐变
|
||||
- base -= 2(顺时针),frame++
|
||||
⑥ frame >= 100 后触发首次启动检测:
|
||||
- 有 block_read → FAT32 读 "FIRSTINTXT"
|
||||
- firstInit == '0' → 首次启动
|
||||
- firstInit != '0' 或文件不存在 → 正常启动
|
||||
⑦ 首次启动时调度系统初始化器(见 §6)
|
||||
⑧ frame > 150 后跳转 FirstInit.elf
|
||||
```
|
||||
|
||||
### 5.3 视觉体验设计
|
||||
|
||||
**渐变背景**:`BG_TOP = 0xFFC8E0F0`(淡蓝)→ `BG_BOTTOM = 0xFF49306F`(深紫),按屏幕 y 坐标线性插值。FirstInit 复用相同背景语义,保证转场连续。
|
||||
|
||||
**旋转加载环**:
|
||||
- 中心 `(cx, cy) = (fb_w/2, fb_h/2)`,半径 `r=48`,厚度 `thk=4`。
|
||||
- 四色弧:`arcs = {0xFF4488CC, 0xFF2266AA, 0xFF66AAEE, 0xFF88CCFF}`,每段 90°,宽 82°。
|
||||
- comet-tail:弧两端 6° 范围内 alpha 渐变(fade 0→255→0),形成拖尾。
|
||||
- 内圆高光:`r-8` 范围内用背景色与白色 `(0xD0,0xF0,0xFF)` 混合,营造光晕。
|
||||
- 纯整数运算(无浮点依赖),`isqrt_int` 用牛顿迭代。
|
||||
|
||||
**帧率控制**:`for(volatile u32 d=0; d<72000; d++) __asm__("pause")`——约 60fps(QEMU 下)。
|
||||
|
||||
### 5.4 B3 锚点
|
||||
|
||||
```text
|
||||
[DSK] block_read ptr=0x...
|
||||
[DSK] entering spinner loop
|
||||
[DSK] checking firstInit...
|
||||
[DSK] fat32 reading 256 sectors from LBA 0
|
||||
[DSK] firstInit=0 ← 首次启动判定
|
||||
[DSK] first init detected; running system initializers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 系统初始化器调度协议
|
||||
|
||||
### 6.1 设计原则
|
||||
|
||||
DSK **独占系统组件初始化职责**。FirstInit 只负责用户级设置(计算机名/用户名/密码),不接管系统初始化。这一边界避免"用户向导"与"系统初始化"逻辑耦合。
|
||||
|
||||
### 6.2 调度顺序(首次启动)
|
||||
|
||||
```text
|
||||
DSK (firstInit == 0)
|
||||
→ ① mouseInit.elf 系统输入初始化(PS/2 鼠标安全 stub)
|
||||
DSK 调用 → mouseInit 执行 → 返回 DSK
|
||||
→ ② netman.elf 网络管理器(配置加载 + netdev 枚举 + DHCP)
|
||||
DSK 调用 → netman 执行 → 返回 DSK
|
||||
→ ③ FirstInit.elf 用户设置向导
|
||||
DSK 调用 → FirstInit 接管 UI → 不返回(halt)
|
||||
```
|
||||
|
||||
### 6.3 初始化器 ELF 加载
|
||||
|
||||
DSK 用内嵌 FAT32 解析器 + PIE ELF loader 加载每个初始化器:
|
||||
|
||||
```text
|
||||
fat32_read_root_file("MOUSE ELF", &data, &size)
|
||||
→ dsk_load_elf(data, size, &entry)
|
||||
→ 校验 ELF64 / EM_X86_64
|
||||
→ PT_LOAD 复制到静态 image buffer
|
||||
→ PT_DYNAMIC → DT_RELA/DT_RELASZ → R_X86_64_RELATIVE 重定位
|
||||
(*slot = load_bias + addend)
|
||||
→ entry = image + (e_entry - min_vaddr)
|
||||
→ entry(ctx) # 传入同一 dsk_boot_context
|
||||
```
|
||||
|
||||
**关键约束**:
|
||||
- PIE ELF 必须处理 `R_X86_64_RELATIVE`——否则解引用全局指针/数组会 page fault。
|
||||
- 指针数组改用栈上 `char[]` 逐字节赋值——避免 UTSM loader 不处理 `.rela.dyn` 的问题。
|
||||
- ELF 文件大小不能超过静态缓冲区(`g_fdata[262144]` = 256KB),`dsk_load_elf` 必须校验 `found_size <= sizeof(g_fdata)`。
|
||||
- 8.3 文件名必须用栈上字符数组构造,避免 PIE 重定位(`char name[12]; name[0]='F'; ...`)。
|
||||
|
||||
### 6.4 各初始化器职责
|
||||
|
||||
| 初始化器 | 产物 | 当前状态 | 职责 |
|
||||
|---------|------|---------|------|
|
||||
| **mouseInit** | `mouse/mouseInit.elf` | 安全 stub | 只读 PS/2 状态,不写控制器(避免 QEMU 早期阶段阻塞) |
|
||||
| **netman** | `network/netman.elf` | 配置闭环 | 读 `conf.conf`/`NETCONF.CNF`,枚举 netdev,e1000 最小 DHCP |
|
||||
| **FirstInit** | `user/use/FirstInit.elf` | UI + 输入 | 环淡出 → "欢迎使用 Deshab" → 账户设置卡片 → 键盘输入 → SHA256 密码 |
|
||||
|
||||
---
|
||||
|
||||
## 7. B4 Excitas — 唤醒
|
||||
|
||||
### 7.1 首次启动路径
|
||||
|
||||
```text
|
||||
FirstInit.elf (dsk_entry → entry(ctx))
|
||||
① 接收 dsk_boot_context,复用 framebuffer
|
||||
② 加载环淡出动画(~1秒渐变)
|
||||
③ 屏幕中央:"欢迎使用 Deshab"(预渲染 24px 中文位图,180×30)
|
||||
④ 等待 5 秒
|
||||
⑤ 渐隐切换为:"接下来让我们来引导你设置你的系统"
|
||||
⑥ 账户设置卡片:
|
||||
- 圆角矩形(draw_card,isqrt_int 边界检查)
|
||||
- 白色输入框(INPUT_BG = 0xFFF0F5FA)
|
||||
- 18px 中文(text_bitmaps.c 预渲染嵌入 ELF)
|
||||
⑦ PS/2 键盘轮询输入:计算机名 → 用户名 → 密码
|
||||
⑧ SHA256 密码摘要 + XOR 加密配置缓冲(user.conf 格式)
|
||||
⑨ "设置完成"提示
|
||||
⑩ for(;;) hlt # 当前不返回,待写盘后跳转正常启动
|
||||
```
|
||||
|
||||
**字体方案**:
|
||||
- 预渲染中文位图:`CODE/font/render_embedded.py` 用 Pillow 从 `simhei.ttf` 渲染指定字符串为 8bpp 灰度 C 数组,嵌入 ELF,避免运行时 TTF 解析。
|
||||
- 运行时字体:DBF 格式(`simhei_16/24/32.dbf`),GB2312 全部 6763 汉字 + ASCII,索引按 codepoint 升序二分查找。
|
||||
|
||||
### 7.2 正常启动路径(待实现)
|
||||
|
||||
```text
|
||||
firstInit != 0(或文件不存在)
|
||||
→ B3 检测到非首次启动
|
||||
→ 跳过系统初始化器调度
|
||||
→ frame > 800 后 break 退出 spinner
|
||||
→ [DSK] SELFTEST PASS
|
||||
→ for(;;) hlt
|
||||
```
|
||||
|
||||
当前正常启动路径仅 halt。未来将进入:
|
||||
- 桌面环境 / Shell
|
||||
- 用户登录验证(读取 user.conf,校验密码)
|
||||
- 后台服务启动
|
||||
|
||||
### 7.3 首次→正常的转换条件
|
||||
|
||||
首次启动完成后,需写 `firstInit.txt = '1'` 以标记已完成。当前**写盘待实现**(依赖 `dkm_block_api.write` + AHCI WRITE DMA + FAT32 文件覆写,见 [路线图](./ROADMAP.md) Phase 5)。
|
||||
|
||||
### 7.4 B4 锚点
|
||||
|
||||
```text
|
||||
[DSK] jumping to mouseInit
|
||||
[mouse] init done
|
||||
[DSK] mouseInit returned
|
||||
[DSK] jumping to netman
|
||||
[netman] ...
|
||||
[DSK] netman returned
|
||||
[DSK] loading FirstInit.elf
|
||||
[DSK] FirstInit.elf loaded
|
||||
[DSK] jumping to FirstInit ← B4 锚点(稳定点 3)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 启动错误恢复
|
||||
|
||||
### 8.1 当前回退链
|
||||
|
||||
| 失败点 | 回退策略 | 日志 |
|
||||
|--------|---------|------|
|
||||
| B2 FAT32 block provider 不可用 | 回退 Limine module | `[UTSM] FAT32 block path unavailable; trying Limine module` |
|
||||
| B2 DSK module 两路径都找不到 | panic | `[UTSM] DSK module not found (neither FAT32 nor Limine)` |
|
||||
| B2 ELF 校验失败 | panic | `[UTSM] DSK ELF rejected` |
|
||||
| B3 无 block device | 跳过 firstInit,正常启动 | `[DSK] no block device, skipping firstInit` |
|
||||
| B3 firstInit.txt 不存在 | 视为首次启动 | `[DSK] firstInit.txt not found` |
|
||||
| B3 FirstInit.elf 加载失败 | 继续正常启动 | `[DSK] firstInit not found, continuing normal boot` |
|
||||
| B4 mouseInit.elf 加载失败 | 跳过,继续 netman | (日志无,静默跳过) |
|
||||
| B1 required 驱动失败 | DRR recovery / panic | (DKM 标记 FAILED_REQUIRED) |
|
||||
| B1 optional 驱动失败 | 标记 FAILED,继续 | (DKM 标记 FAILED_*) |
|
||||
|
||||
### 8.2 DRR 接管路径(未来)
|
||||
|
||||
DRR(专用恢复根)实现后,启动错误恢复将升级为三级:
|
||||
|
||||
```text
|
||||
Page Rollback 单页损坏,从 checkpoint slot 恢复密文页
|
||||
Segment Rollback 整段损坏,恢复 segment desc / DMP / key_epoch
|
||||
System Rollback 控制面严重损坏,写 crash reason → reboot → bootloader 切 last_good_slot
|
||||
```
|
||||
|
||||
DRR Emergency Pool 独立于普通 allocator,recovery 路径禁止依赖普通堆。详见 [架构设计文档 §3.4](./ARCHITECTURE.md#34-drr--专用恢复根)。
|
||||
|
||||
### 8.3 真机调试特殊处理
|
||||
|
||||
QEMU 不严格检查 NX,真机 Limine page table 会强制 NX。以下问题只在真机暴露,需特殊处理:
|
||||
|
||||
- `kernel_panic` 应直接通过 COM1 串口输出,**不依赖 console/heap**。
|
||||
- 添加分步 `screen_info()` 便于真机调试。
|
||||
- 早期 `IA32_GS_BASE` 必须设置,否则栈保护 prologue 页错误。
|
||||
|
||||
---
|
||||
|
||||
## 9. 启动状态传递链
|
||||
|
||||
启动过程中,系统状态通过三级指针链传递给 DSK 及其初始化器:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
L["Limine response<br/>memmap/RSDP/fb/module/HHDM"] -->|"kernel_main 读取"| UTSM["UTSM 内核"]
|
||||
UTSM -->|"dkm_fill_platform_info<br/>填充 kernel_api"| API["dkm_kernel_api<br/>log/irq/dma/block/net/..."]
|
||||
API -->|"dsk_fill_boot_context<br/>ctx->dkm_kernel_api"| CTX["dsk_boot_context"]
|
||||
CTX -->|"dsk_entry(ctx)<br/>RDI"| DSK["DSK 主内核"]
|
||||
DSK -->|"同一 ctx 传递"| INIT["mouseInit / netman / FirstInit"]
|
||||
INIT -->|"ctx->dkm_kernel_api<br/>+ 0xA8 取 block_read"| BLK["block provider<br/>(ahci0)"]
|
||||
INIT -->|"ctx->dkm_kernel_api<br/>+ net 偏移"| NET["netdev registry<br/>(e1000/virtio_net)"]
|
||||
```
|
||||
|
||||
**关键约束**:
|
||||
- DSK 及所有初始化器共享同一个 `dsk_boot_context`,通过它访问所有内核服务。
|
||||
- `block_read` 通过硬偏移 `api + 0xA8` 读取——偏移错误会导致 NULL 解引用(曾因误用 `0x60` 导致 `g_block_read` 永远为 NULL)。
|
||||
- 所有初始化器都是 PIE ELF,DSK loader 必须处理 `R_X86_64_RELATIVE`。
|
||||
|
||||
---
|
||||
|
||||
## 10. 启动阶段与架构映射
|
||||
|
||||
| 启动阶段 | 架构子系统 | 涉及源码 |
|
||||
|---------|-----------|---------|
|
||||
| B0 Ignis | Limine bootloader | `SYSTEM/EFI/BOOT/` `SYSTEM/boot/limine.conf` |
|
||||
| B1 Sigillum | UTSM + DKM + DMA + IDT | `CODE/UTSM/` `CODE/DKM/` |
|
||||
| B2 Transitus | DSK loader + FAT32 + block provider | `CODE/UTSM/kernel/dsk_loader.c` `CODE/UTSM/kernel/block.c` |
|
||||
| B3 Origo | DSK 主内核 + FAT32 内嵌解析 | `CODE/dsk/main.c` |
|
||||
| B4 Excitas | FirstInit + mouseInit + netman + 字体 | `CODE/firstInit/` `CODE/mouse/` `CODE/netman/` `CODE/font/` |
|
||||
|
||||
---
|
||||
|
||||
## 11. 启动验证标准
|
||||
|
||||
### 11.1 最小启动验证(QEMU 默认场景)
|
||||
|
||||
```text
|
||||
[UTSM] boot ← B1 开始
|
||||
[UTSM] SELFTEST PASS ← B1 锚点
|
||||
[UTSM] loading DSK
|
||||
[UTSM] DSK loaded from FAT32 block provider ← 或 Limine module
|
||||
[UTSM] jumping to DSK
|
||||
[DSK] boot ← B2 锚点
|
||||
[DSK] context ok
|
||||
[DSK] SELFTEST PASS ← B3 正常启动锚点
|
||||
```
|
||||
|
||||
### 11.2 首次启动完整验证(带 SATA FAT32 测试盘)
|
||||
|
||||
```text
|
||||
[UTSM] boot
|
||||
[UTSM] SELFTEST PASS
|
||||
[UTSM] loading DSK
|
||||
[DSK] boot
|
||||
[DSK] context ok
|
||||
[DSK] block_read ptr=0x...
|
||||
[DSK] entering spinner loop
|
||||
[DSK] checking firstInit...
|
||||
[DSK] fat32 reading 256 sectors from LBA 0
|
||||
[DSK] firstInit=0
|
||||
[DSK] first init detected; running system initializers
|
||||
[DSK] jumping to mouseInit
|
||||
[mouse] init done
|
||||
[DSK] mouseInit returned
|
||||
[DSK] jumping to netman
|
||||
[DSK] netman returned
|
||||
[DSK] loading FirstInit.elf
|
||||
[DSK] FirstInit.elf loaded
|
||||
[DSK] jumping to FirstInit ← B4 锚点
|
||||
(屏幕显示:渐变背景 → 旋转环 → "欢迎使用 Deshab" → 账户设置卡片)
|
||||
```
|
||||
|
||||
### 11.3 设备测试场景
|
||||
|
||||
| 场景 | QEMU 参数 | 验证锚点 |
|
||||
|------|----------|---------|
|
||||
| SATA 块设备 | 临时 SATA FAT32 测试盘 | `block_read ptr` 非 NULL,FAT32 读取成功 |
|
||||
| NVMe | `-device nvme` | 探测 `1b36:0010`(register 读取依赖高位 MMIO) |
|
||||
| e1000 网络 | `-device e1000e` | netdev `tx=ready rx=ready` |
|
||||
| virtio-net | `-netdev user` + `-device virtio-net-pci` | 探测 `1af4:1001` |
|
||||
|
||||
---
|
||||
|
||||
## 12. 相关文档
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [架构设计文档](./ARCHITECTURE.md) | 五大核心子系统、内存模型、驱动系统 |
|
||||
| [开发路线图](./ROADMAP.md) | 分阶段开发路线(Phase 0-9) |
|
||||
| [DSK 主内核说明](../CODE/dsk/README) | DSK boot context 与加载要求 |
|
||||
| [UTSM 模块设计](../CODE/UTSM/README.md) | 封缄内存与启动流程 §16 |
|
||||
| [DKM 驱动系统](../CODE/DKM/README.md) | 驱动分阶段加载与状态机 |
|
||||
| [CLAUDE.md](../CLAUDE.md) | 项目当前状态与下一阶段路线 |
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
# Deshab-OS 开发路线图
|
||||
|
||||
> 本文档基于项目当前实现状态与各模块规划,给出分阶段开发路线。
|
||||
> 状态标记:✅ 已完成 · 🔶 部分完成 · ⬜ 待实现
|
||||
|
||||
---
|
||||
|
||||
## 当前状态总览
|
||||
|
||||
Deshab-OS 已完成**可启动的实验内核**闭环:
|
||||
|
||||
```text
|
||||
Limine → utsm.elf → DKM 14 驱动加载 → DSK (deshab.elf)
|
||||
→ 旋转加载动画 → 首次启动检测
|
||||
→ firstInit=0: mouseInit → FirstInit 用户设置向导(中文 UI / SHA256 密码)
|
||||
→ firstInit≠0: 正常启动(待实现)
|
||||
```
|
||||
|
||||
| 子系统 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 早期启动(serial/IDT/PIC) | ✅ | IDT 0–47,PIC remap 0x20–0x2f |
|
||||
| UTSM 封缄内存 | 🔶 | selftest 闭环,占位 XOR stream,真实加密待实现 |
|
||||
| DKM 驱动加载 | ✅ | 14/14 驱动 discovery + 加载闭环 |
|
||||
| DMA 分配器 | ✅ | Limine USABLE → 物理页 bitmap,低 4G 钳位 |
|
||||
| AHCI 块设备 | 🔶 | IDENTIFY/READ DMA + block provider,无 write |
|
||||
| NVMe | 🔶 | PCI discovery only,BAR0 在 4G 以上待映射 |
|
||||
| FAT32 | 🔶 | 只读,优先 block provider 回退 boot module |
|
||||
| e1000 网络 | 🔶 | 完整 RX/TX ring,无协议栈 |
|
||||
| virtio_net | 🔶 | PCI discovery + capability 枚举,无 virtqueue |
|
||||
| 字体系统 | ✅ | DBF 格式 16/24/32px,GB2312 全覆盖 |
|
||||
| FirstInit | 🔶 | 中文 UI + 键盘输入 + SHA256 密码,写盘待实现 |
|
||||
| SAS-R0-PCQ 调度器 | ⬜ | 设计完成,未实现 |
|
||||
| DRR 恢复根 | ⬜ | stub 占位,未实现 |
|
||||
|
||||
---
|
||||
|
||||
## 路线图总览
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
P0["Phase 0<br/>内存与 MMIO 底座"] --> P1["Phase 1<br/>DMA 与块设备数据路径"]
|
||||
P1 --> P2["Phase 2<br/>IRQ 后端升级"]
|
||||
P2 --> P3["Phase 3<br/>网络数据路径"]
|
||||
P1 --> P4["Phase 4<br/>VFS 与真实块设备接入"]
|
||||
P4 --> P5["Phase 5<br/>block write 与 FAT32 write"]
|
||||
P5 --> P6["Phase 6<br/>FirstInit 完善"]
|
||||
P2 --> P7["Phase 7<br/>SAS-R0-PCQ 调度器"]
|
||||
P7 --> P8["Phase 8<br/>DRR 恢复系统"]
|
||||
P8 --> P9["Phase 9<br/>真实加密落地"]
|
||||
```
|
||||
|
||||
**优先级原则**(源自 [DSK README](../CODE/dsk/README) §7):
|
||||
|
||||
> 先让 UTSM 能加载并跳到 DSK → 再补内存/MMIO/DMA → 再做块设备真实读取 → 再迁移文件系统和网络数据路径 → 最后进入调度器和恢复系统深化。
|
||||
|
||||
---
|
||||
|
||||
## Phase 0 — 内存与 MMIO 底座
|
||||
|
||||
**目标**:建立物理页分配器、页表映射接口、高位 PCI MMIO 映射能力,解决 NVMe 4G 以上 BAR 和后续 DMA 映射问题。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| 物理页 bitmap 分配器 | ✅ | Limine USABLE → bitmap,已根治 e1000 DMA |
|
||||
| 页表映射接口(map/unmap) | ⬜ | 提供 `mmio_map(phys, size, flags)` 通用接口 |
|
||||
| 高位 PCI MMIO 映射(4G 以上 BAR) | ⬜ | NVMe BAR0 可安全读取 register |
|
||||
| 替换 arena 为真实页分配 | ⬜ | DKM 驱动加载使用物理页分配器,移除 16MB arena 上限 |
|
||||
|
||||
**依赖**:无(基础设施)
|
||||
|
||||
**风险**:页表操作需在关中断下小心进行;高位 MMIO 映射需建立独立页表项,避免破坏 HHDM。
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — DMA 与块设备数据路径
|
||||
|
||||
**目标**:建立 contiguous DMA buffer、cache/屏障约定、PRDT/队列内存管理,推进 AHCI/NVMe 真实读写。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| DMA buffer 统一接口(alloc/sync_for_device/sync_for_cpu) | 🔶 | `dkm_dma_api` 已定义,cache 屏障约定待完善 |
|
||||
| AHCI IDENTIFY/READ | ✅ | SATA 盘可读取 LBA0 |
|
||||
| AHCI 多扇区批量 read 稳定化 | 🔶 | 256 扇区批量读成功,单扇区偶发超时待收敛 |
|
||||
| AHCI block provider 注册 | ✅ | `ahci0` 注册到 `kernel_api.block` |
|
||||
| NVMe admin queue / identify | ⬜ | 依赖 Phase 0 高位 MMIO |
|
||||
| NVMe block provider | ⬜ | 注册 `nvme0`,支持 READ |
|
||||
|
||||
**依赖**:Phase 0
|
||||
|
||||
**风险**:AHCI command header 布局须严格按规范;不对 ATAPI/空端口发 ATA IDENTIFY。
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — IRQ 后端升级
|
||||
|
||||
**目标**:在 PIC fallback 稳定基础上扩展 IDT/vector allocator/APIC EOI/IOAPIC redirection,逐步迁移设备 IRQ,最后接入 MSI/MSI-X。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| IDT 扩展到 256 vectors | 🔶 | 当前 0–47 stub |
|
||||
| Vector allocator | ⬜ | 动态分配中断向量 |
|
||||
| APIC EOI 后端 | ⬜ | 替代 PIC EOI |
|
||||
| IOAPIC redirection | ⬜ | 迁移设备 IRQ 到 IOAPIC |
|
||||
| LAPIC timer | ⬜ | 替代 PIT 作为调度时钟 |
|
||||
| MSI / MSI-X | ⬜ | NVMe/e1000 使用 MSI-X |
|
||||
|
||||
**依赖**:无(可与 Phase 1 并行)
|
||||
|
||||
**风险**:未扩展 IDT/vector allocator 前不能禁用 PIC 或重编 IOAPIC RTE,否则中断投递和 EOI 后端不一致。
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — 网络数据路径
|
||||
|
||||
**目标**:在 DMA/IRQ 完成后推进 e1000 与 virtio-net 的完整收发能力。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| e1000 完整 RX/TX ring | ✅ | netdev flags `LINK_UP|TX_READY|RX_READY` |
|
||||
| e1000 中断驱动收发 | ⬜ | 替代 polling,接 IOAPIC/MSI(依赖 Phase 2) |
|
||||
| virtio-net feature negotiation | ⬜ | 完成 device_status / feature_select |
|
||||
| virtio-net virtqueue RX/TX | ⬜ | 建队列、收发包 |
|
||||
| 最小协议栈(ARP/IP/UDP/DHCP/DNS) | ⬜ | netman 可完成 DHCP 获取地址 |
|
||||
|
||||
**依赖**:Phase 1(DMA)、Phase 2(IRQ)
|
||||
|
||||
**风险**:网卡中断早期开启容易刷屏或阻塞,IOAPIC/MSI 完善前保持 masked,收发先走 polling。
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — VFS 与真实块设备接入
|
||||
|
||||
**目标**:将 FAT32 从测试镜像迁移到 AHCI/NVMe block provider,完善挂载、读取、目录遍历和错误路径。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| FAT32 接入真实 block provider | 🔶 | 优先 block provider,回退 boot module |
|
||||
| FAT32 子目录路径解析 | ⬜ | 支持 `/system/deshab64/deshab.elf` 完整路径 |
|
||||
| VFS 统一路径语义 | ⬜ | DSK 加载与 VFS 路径统一 |
|
||||
| 目录遍历 | ⬜ | 支持枚举目录项 |
|
||||
| 错误路径完善 | ⬜ | block read 失败 / BPB 无效正确回退 |
|
||||
|
||||
**依赖**:Phase 1(块设备)
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — block write 与 FAT32 write
|
||||
|
||||
**目标**:实现块设备写和 FAT32 文件写入,支撑配置持久化。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| `dkm_block_api.write` | ⬜ | AHCI 实现 WRITE DMA |
|
||||
| FAT32 文件创建 | ⬜ | 写目录项 |
|
||||
| FAT32 FAT 链更新 | ⬜ | 分配新 cluster |
|
||||
| FAT32 文件覆写 | ⬜ | user.conf / firstInit.txt 写盘 |
|
||||
| firstInit.txt 标志写盘 | ⬜ | 首次启动后写 `1` |
|
||||
|
||||
**依赖**:Phase 1(块设备)、Phase 4(VFS)
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 — FirstInit 完善
|
||||
|
||||
**目标**:完善首次启动用户设置向导的完整功能。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| 修复 FirstInit 按键崩溃 | 🔶 | `fb_text` 在 `-O2` 下稳定 |
|
||||
| 鼠标光标移动 | ⬜ | PS/2 IRQ12 + 包解码 + 光标更新 |
|
||||
| user.conf 写盘 | ⬜ | 依赖 Phase 5 block write |
|
||||
| 网络配置界面 | ⬜ | IP/DHCP/网关设置 |
|
||||
| 时区/语言选择 | ⬜ | — |
|
||||
| 设置完成后跳转正常启动 | ⬜ | 写 firstInit=1,跳转 DSK 正常路径 |
|
||||
| 正常启动路径 | ⬜ | firstInit≠0 时的桌面/Shell |
|
||||
|
||||
**依赖**:Phase 3(网络)、Phase 5(写盘)
|
||||
|
||||
---
|
||||
|
||||
## Phase 7 — SAS-R0-PCQ 调度器
|
||||
|
||||
**目标**:实现单地址空间 Ring0 任务模型与 Per-CPU O(1) 位图调度器。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| TCB 与 task_create 流程 | ⬜ | 分配 TCB、生成 process_uuid、创建 stack/heap 段、capability table |
|
||||
| Per-CPU runqueue | ⬜ | 每 CPU 独立 runqueue |
|
||||
| O(1) 位图调度器 | ⬜ | pick_next_task 为 O(1) |
|
||||
| context_switch | ⬜ | utsm_switch_out / utsm_switch_in 只加载 crypto 指针 |
|
||||
| task_kill crypto erase | ⬜ | owned segment key_epoch++,state=DESTROYED |
|
||||
| SMP 多核 | ⬜ | 多核调度(可选,后续) |
|
||||
|
||||
**依赖**:Phase 0(内存)
|
||||
|
||||
**风险**:调度切换路径禁止扫描 capability、计算 MAC、重加密——必须保持 O(1)。
|
||||
|
||||
---
|
||||
|
||||
## Phase 8 — DRR 恢复系统
|
||||
|
||||
**目标**:实现专用恢复根的看门狗、checkpoint、recovery log、A-B 回滚。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| DRR Emergency Pool | ⬜ | 独立紧急内存池,普通 allocator 不可用 |
|
||||
| Watchdog | ⬜ | 独立于普通调度器 |
|
||||
| Recovery log | ⬜ | WRITE_INTENT / WRITE_COMMIT log 对 |
|
||||
| Dirty Shard + Dirty Bitmap | 🔶 | 数据结构已设计,实现待补 |
|
||||
| A/B Checkpoint metadata 双槽 | ⬜ | CRC 校验 + 原子 active slot 切换 |
|
||||
| Page / Segment / System Rollback | ⬜ | 三级回滚 |
|
||||
| 驱动 recovery ops(quiesce/reset/reinit) | ⬜ | DRR 驱动故障恢复 |
|
||||
|
||||
**依赖**:Phase 7(调度器)、UTSM 真实加密(Phase 9)
|
||||
|
||||
**风险**:恢复路径禁止依赖普通堆;checkpoint 提交顺序固定不可调;Emergency Pool 耗尽直接 system rollback。
|
||||
|
||||
---
|
||||
|
||||
## Phase 9 — 真实加密落地
|
||||
|
||||
**目标**:将 UTSM 占位 XOR stream 替换为真实加密原语。
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| 确定加密原语(KDF/hash/stream/MAC) | ⬜ | 选定 HKDF/BLAKE2/AES-CTR/Poly1305 等 |
|
||||
| KDF 实现 | ⬜ | `segment_key = KDF(root_key, process_uuid, segment_uuid, key_epoch)` |
|
||||
| Stream cipher 实现 | ⬜ | 64B cache line 级加解密 |
|
||||
| MAC 实现 | ⬜ | 4KB page 粒度 MAC |
|
||||
| DRR root key 管理 | ⬜ | root key 生成 / 存储 / 轮换 |
|
||||
| PCKC key schedule 缓存 | ⬜ | 真实 key schedule 而非占位 |
|
||||
|
||||
**依赖**:Phase 8(DRR root key)
|
||||
|
||||
**风险**:加密原语需在 `-mno-sse` 下可用(或在此阶段启用 SSE/SIMD);性能需保持热路径 O(1)。
|
||||
|
||||
---
|
||||
|
||||
## DKM 工程化收尾(贯穿各阶段)
|
||||
|
||||
| 任务 | 状态 | 验收标准 |
|
||||
|------|------|---------|
|
||||
| 统一驱动本地 ABI 公共头 | ⬜ | 移除各驱动内联 `dkm_kernel_api` 定义 |
|
||||
| kernel_api typed sub-struct 迁移 | ⬜ | `const void *` 占位 → typed 指针 |
|
||||
| 清理编译 warning | ⬜ | `-Wall -Wextra` 零警告 |
|
||||
| QEMU 场景自动化 | ⬜ | e1000/virtio-net/nvme/ahci 独立测试场景 |
|
||||
| log API printf 变参支持 | ⬜ | 统一为 `(*info)(const char *fmt, ...)` |
|
||||
|
||||
---
|
||||
|
||||
## 里程碑
|
||||
|
||||
| 里程碑 | 完成阶段 | 标志 |
|
||||
|--------|---------|------|
|
||||
| **M1 — 真实块设备启动** | Phase 0+1+4 | 从 AHCI/NVMe FAT32 读取 deshab.elf,脱离 test.fat32 |
|
||||
| **M2 — 配置持久化** | Phase 5+6 | FirstInit 设置可写盘,重启后正常启动 |
|
||||
| **M3 — 网络可用** | Phase 2+3 | DHCP 获取地址,可收发 UDP |
|
||||
| **M4 — 多任务调度** | Phase 7 | SAS-R0-PCQ 调度器运行多任务 |
|
||||
| **M5 — 容错恢复** | Phase 8+9 | DRR checkpoint/rollback + 真实加密 |
|
||||
|
||||
---
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [架构设计文档](./ARCHITECTURE.md)
|
||||
- [贡献与协作规范](../CONTRIBUTING.md)
|
||||
- [CLAUDE.md](../CLAUDE.md) — 项目当前状态与下一阶段路线
|
||||
- [LESSONS_LEARNED.md](../LESSONS_LEARNED.md) — 开发经验教训
|
||||
Reference in New Issue
Block a user