OHHHHH
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
# Deshab Bug 记录
|
||||
|
||||
> 所有测试与开发过程中发现的 bug 统一登记于此。每个 bug 按 BUG-YYYYMMDD-NNN 编号。
|
||||
> 测试用例文档位于 RE/test-cases/。
|
||||
|
||||
## 严重程度定义
|
||||
|
||||
- P0 阻断: 影响主链路启动或核心功能完全不可用(必须立即修复)
|
||||
- P1 严重: 功能可降级但关键路径受损(本轮内修复)
|
||||
- P2 一般: 非关键路径异常或体验问题(下一里程碑前修复)
|
||||
- P3 提示: 日志/小问题,不影响功能(记录备查)
|
||||
|
||||
## Bug 条目格式
|
||||
|
||||
```
|
||||
### BUG-YYYYMMDD-NNN [P级] [模块] 简述
|
||||
- 现象:
|
||||
- 复现步骤:
|
||||
- 串口/日志证据:
|
||||
- 根因分析:
|
||||
- 修复方案:
|
||||
- 状态: [OPEN/FIXING/FIXED/CLOSED]
|
||||
- 修复提交: <commit hash 或 "待提交">
|
||||
- 验证: <验证方法与结果>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bug 列表
|
||||
|
||||
<!-- 在此追加 bug 条目,最新放在顶部 -->
|
||||
P2: 软件Files的窗口点击叉无法关闭
|
||||
P3: 在第一页已经有了终端,所以在第四页的桌面上不用显示终端和CMD
|
||||
P2: 在开发者模式中的shell输入命令并回车时文字消失没有反应
|
||||
P3: 启动时的打字机效果再快3倍
|
||||
P2: 桌面中第一页的shell中输入命令回车后,上一条命令输入的文字会跑到下一行
|
||||
P2: 桌面中第一页的Files显示的不是SYSTEM/user中的文件夹内容
|
||||
P2: Files中没有显示文件夹,直接显示了文件夹下的文件
|
||||
P2: Files没有提供“..”来供用户返回上一级的文件夹
|
||||
@@ -0,0 +1,504 @@
|
||||
# UTSM 算法记录
|
||||
|
||||
```text
|
||||
UTSM = UUID-Tuned Sealed Memory
|
||||
中文名:UUID 调谐封缄内存
|
||||
```
|
||||
|
||||
本文记录 UTSM v1 的核心算法。
|
||||
|
||||
---
|
||||
|
||||
## 1. 段创建算法
|
||||
|
||||
目标:为任务创建一个只存密文的连续内存段,并返回 capability。
|
||||
|
||||
```text
|
||||
utsm_create_segment(process, size, flags)
|
||||
1. size 按 64B / 4KB 对齐。
|
||||
2. 从 buddy/slab 分配 cipher data pages。
|
||||
3. 从 DMP pool 分配 DMP。
|
||||
4. 生成 segment_uuid。
|
||||
5. key_epoch = process.crypto_epoch。
|
||||
6. tweak_seed = hash(process_uuid, segment_uuid, key_epoch)。
|
||||
7. 初始化 dirty_bitmap。
|
||||
8. 初始化 mac_table。
|
||||
9. 填写 utsm_segment_desc。
|
||||
10. 填写 utsm_dmp。
|
||||
11. generation++。
|
||||
12. 生成 utsm_capability。
|
||||
13. 将 capability 写入任务 capability table。
|
||||
14. 返回 capability。
|
||||
```
|
||||
|
||||
复杂度:
|
||||
|
||||
```text
|
||||
段元数据初始化:O(1)
|
||||
数据页分配:O(page_count)
|
||||
热路径访问定位:O(1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 密钥派生算法
|
||||
|
||||
UUID 不作为明文密钥,而是作为调谐因子。
|
||||
|
||||
```text
|
||||
segment_key = KDF(
|
||||
DRR_root_key,
|
||||
process_uuid,
|
||||
segment_uuid,
|
||||
key_epoch
|
||||
)
|
||||
```
|
||||
|
||||
每 64B cache line 生成 tweak:
|
||||
|
||||
```text
|
||||
line_index = offset / 64
|
||||
tweak = hash(tweak_seed, line_index, key_epoch)
|
||||
```
|
||||
|
||||
加密和解密对称:
|
||||
|
||||
```text
|
||||
ciphertext = plaintext XOR stream(segment_key, tweak)
|
||||
plaintext = ciphertext XOR stream(segment_key, tweak)
|
||||
```
|
||||
|
||||
设计理由:
|
||||
|
||||
```text
|
||||
1. 避免十进制 UUID 解析。
|
||||
2. 避免 UUID 孔洞破坏连续内存。
|
||||
3. 以 64B cache line 为单位,适合 CPU cache 和 SIMD。
|
||||
4. key_epoch 可用于快速作废旧段。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. UTRW Fast Read 算法
|
||||
|
||||
```text
|
||||
UTRW_READ_FAST(cap, offset, len, dst)
|
||||
1. desc = SEGMENT_TABLE[cap.segment_slot]。
|
||||
2. 检查 desc.generation == cap.generation。
|
||||
3. 检查 cap.rights 包含 READ。
|
||||
4. 检查 cap.epoch == desc.key_epoch。
|
||||
5. 检查 offset + len <= desc.cipher_length。
|
||||
6. 检查 desc.state == ACTIVE。
|
||||
7. key = PCKC_LOOKUP(desc.segment_slot, desc.key_epoch)。
|
||||
8. 如果 key miss,进入 slow path。
|
||||
9. 读取 writer_seq_before。
|
||||
10. 如果 writer_seq_before 为奇数,重试或 slow path。
|
||||
11. 对访问范围涉及的每个 64B line:
|
||||
a. 计算 line_index。
|
||||
b. 生成 tweak。
|
||||
c. 读取密文 line。
|
||||
d. 解密成明文 line。
|
||||
e. 拷贝目标字节到 dst。
|
||||
12. 读取 writer_seq_after。
|
||||
13. 如果 before != after,重试。
|
||||
14. 返回 OK。
|
||||
```
|
||||
|
||||
复杂度:
|
||||
|
||||
```text
|
||||
段定位:O(1)
|
||||
读写长度 n:O(n / 64)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. UTRW Fast Write 算法
|
||||
|
||||
```text
|
||||
UTRW_WRITE_FAST(cap, offset, len, src)
|
||||
1. desc = SEGMENT_TABLE[cap.segment_slot]。
|
||||
2. 检查 desc.generation == cap.generation。
|
||||
3. 检查 cap.rights 包含 WRITE。
|
||||
4. 检查 cap.epoch == desc.key_epoch。
|
||||
5. 检查 offset + len <= desc.cipher_length。
|
||||
6. 检查 desc.state == ACTIVE。
|
||||
7. key = PCKC_LOOKUP(desc.segment_slot, desc.key_epoch)。
|
||||
8. 如果 key miss,进入 slow path。
|
||||
9. 如果是强恢复段,写 WRITE_INTENT log。
|
||||
10. writer_seq++,进入奇数写入状态。
|
||||
11. 对访问范围涉及的每个 64B line:
|
||||
a. 计算 line_index。
|
||||
b. 生成 tweak。
|
||||
c. 如果覆盖完整 line,直接使用 src 明文。
|
||||
d. 如果部分覆盖 line,读取旧密文,解密旧明文,合并新明文。
|
||||
e. 加密成新密文。
|
||||
f. 写回 cipher data。
|
||||
12. 标记 dirty_bitmap。
|
||||
13. writer_seq++,回到偶数稳定状态。
|
||||
14. 如果是强恢复段,写 WRITE_COMMIT log。
|
||||
15. 返回 OK。
|
||||
```
|
||||
|
||||
部分写规则:
|
||||
|
||||
```text
|
||||
UTSM 的加密单位是 64B line。
|
||||
如果只写 line 的一部分,必须读旧密文、解密、合并、重新加密整条 line。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. UTRW Slow Path 算法
|
||||
|
||||
Slow Path 触发条件:
|
||||
|
||||
```text
|
||||
PCKC key miss
|
||||
generation mismatch
|
||||
epoch mismatch
|
||||
state != ACTIVE
|
||||
checkpoint busy
|
||||
recovery busy
|
||||
MAC failed
|
||||
segment poisoned
|
||||
out of bounds
|
||||
access denied
|
||||
```
|
||||
|
||||
处理策略:
|
||||
|
||||
```text
|
||||
KEY_MISS
|
||||
-> 派生 segment_key
|
||||
-> 生成 key_schedule
|
||||
-> 写入 PCKC
|
||||
-> 回到 fast path
|
||||
|
||||
STALE_CAPABILITY
|
||||
-> 尝试从 capability table 刷新
|
||||
-> 失败则返回错误
|
||||
|
||||
EPOCH_EXPIRED
|
||||
-> 刷新 cap.epoch 和 auth_tag
|
||||
-> 清除旧 PCKC key
|
||||
-> 回到 fast path
|
||||
|
||||
CHECKPOINT_BUSY
|
||||
-> 短暂等待或写 side log
|
||||
|
||||
RECOVERING
|
||||
-> 阻塞任务,等待 DRR 完成恢复
|
||||
|
||||
MAC_FAILED
|
||||
-> 标记 suspicious page
|
||||
-> 通知 DRR
|
||||
-> 尝试 page rollback
|
||||
|
||||
SEGMENT_POISONED
|
||||
-> 拒绝访问
|
||||
-> 交给 DRR 决定回滚、重建或 kill task
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. PCKC 查找算法
|
||||
|
||||
每 CPU 保存少量热段 key。
|
||||
|
||||
```text
|
||||
PCKC_LOOKUP(slot, epoch)
|
||||
1. 检查 current hot slot。
|
||||
2. 检查 hot_segment_slot[0..N]。
|
||||
3. 如果 slot 和 epoch 均匹配,返回 key_schedule。
|
||||
4. 否则返回 MISS。
|
||||
```
|
||||
|
||||
替换策略:
|
||||
|
||||
```text
|
||||
第一版使用小型 LRU 或替换最冷 slot。
|
||||
```
|
||||
|
||||
建议槽数:
|
||||
|
||||
```text
|
||||
8 个 key slot 起步。
|
||||
高并发或服务型任务可扩展到 16 个。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Checkpoint 算法
|
||||
|
||||
### 7.1 Dirty Shard 标记算法
|
||||
|
||||
Dirty Bitmap 分片为 Dirty Shard,避免 checkpoint 扫描整块大 bitmap。
|
||||
|
||||
```text
|
||||
UTSM_MARK_DIRTY(desc, page_index)
|
||||
1. shard = desc.dirty_shards[page_index / PAGES_PER_SHARD]。
|
||||
2. bit = page_index % PAGES_PER_SHARD。
|
||||
3. 如果 bit 原来是 0:
|
||||
a. 设置 bitmap bit。
|
||||
b. shard.dirty_count++。
|
||||
c. 如果 shard.dirty_count 从 0 变为 1,加入 per-cpu dirty_shard_list。
|
||||
4. 返回。
|
||||
```
|
||||
|
||||
复杂度:
|
||||
|
||||
```text
|
||||
Dirty 标记:O(1)
|
||||
Checkpoint 扫描:O(number_of_dirty_shards + number_of_dirty_pages)
|
||||
```
|
||||
|
||||
### 7.2 A/B Checkpoint Metadata 提交算法
|
||||
|
||||
```text
|
||||
CHECKPOINT_METADATA_COMMIT(gen)
|
||||
1. active = checkpoint.active_slot。
|
||||
2. inactive = opposite(active)。
|
||||
3. 清理 inactive slot 的临时状态。
|
||||
4. 写 inactive.metadata_header。
|
||||
5. 写 segment desc snapshot。
|
||||
6. 写 DMP snapshot。
|
||||
7. 写 dirty shard summary。
|
||||
8. 写 MAC root。
|
||||
9. 写 generation。
|
||||
10. 计算并写 CRC。
|
||||
11. flush inactive slot。
|
||||
12. 原子切换 checkpoint.active_slot = inactive。
|
||||
13. 写 CHECKPOINT_COMMIT log。
|
||||
```
|
||||
|
||||
恢复时:
|
||||
|
||||
```text
|
||||
1. 读取 active slot。
|
||||
2. 校验 generation 和 CRC。
|
||||
3. 如果 active 有效,使用 active。
|
||||
4. 如果 active 无效,校验 fallback slot。
|
||||
5. 如果 fallback 有效,使用 fallback。
|
||||
6. 如果双槽都无效,进入 system rollback。
|
||||
```
|
||||
|
||||
### 7.3 Dirty Page Checkpoint 算法
|
||||
|
||||
```text
|
||||
DRR_CHECKPOINT()
|
||||
1. checkpoint_generation++。
|
||||
2. 写 CHECKPOINT_BEGIN log。
|
||||
3. inactive_slot = opposite(active_slot)。
|
||||
4. 遍历 per-cpu dirty_shard_list。
|
||||
5. 跳过 dirty_count == 0 的 shard。
|
||||
6. 对每个 dirty shard:
|
||||
a. 找到关联 segment。
|
||||
b. desc.state = CHECKPOINTING。
|
||||
c. 冻结 writer。
|
||||
d. flush PWC / per-CPU dirty buffer。
|
||||
e. 只扫描 shard 内 dirty bit。
|
||||
f. 复制 dirty ciphertext page 到 checkpoint region。
|
||||
g. 计算 page MAC。
|
||||
h. 写 dirty shard summary。
|
||||
i. 清 shard bitmap。
|
||||
j. shard.dirty_count = 0。
|
||||
k. desc.state = ACTIVE。
|
||||
7. 写 segment desc snapshot。
|
||||
8. 写 DMP snapshot。
|
||||
9. CHECKPOINT_METADATA_COMMIT(checkpoint_generation)。
|
||||
```
|
||||
|
||||
提交规则:
|
||||
|
||||
```text
|
||||
只有存在 CHECKPOINT_COMMIT 且 CRC 正确的 checkpoint 才是稳定点。
|
||||
中途崩溃的 checkpoint 直接丢弃。
|
||||
A/B metadata 至少保留一个旧稳定点。
|
||||
```
|
||||
|
||||
### 7.4 DRR Emergency Pool 分配算法
|
||||
|
||||
DRR Recovery 路径不能依赖普通 allocator。
|
||||
|
||||
```text
|
||||
DRR_EMERGENCY_ALLOC(size, class)
|
||||
1. 从 DRR emergency pool 的 class freelist 取对象。
|
||||
2. 如果 freelist 非空,返回对象。
|
||||
3. 如果 freelist 为空,从 emergency pages 切分。
|
||||
4. 如果 emergency pages 不足:
|
||||
a. 写 EMERGENCY_POOL_EXHAUSTED。
|
||||
b. 进入 system rollback。
|
||||
```
|
||||
|
||||
Emergency Pool 包含:
|
||||
|
||||
```text
|
||||
DRR private stack
|
||||
recovery log buffer
|
||||
checkpoint metadata buffer
|
||||
crash buffer
|
||||
metadata slab
|
||||
emergency pages
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
```text
|
||||
普通 allocator 不可使用 Emergency Pool。
|
||||
Emergency Pool 不参与普通内存回收。
|
||||
DRR OOM 直接视为不可恢复故障。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Rollback 算法
|
||||
|
||||
分三级。
|
||||
|
||||
### 8.1 Page Rollback
|
||||
|
||||
```text
|
||||
1. 定位最近稳定 checkpoint。
|
||||
2. 校验 checkpoint page MAC。
|
||||
3. 将旧密文页复制回 cipher data。
|
||||
4. 恢复 page MAC。
|
||||
5. 清 dirty bit。
|
||||
6. 段保持 ACTIVE。
|
||||
```
|
||||
|
||||
### 8.2 Segment Rollback
|
||||
|
||||
```text
|
||||
1. desc.state = RECOVERING。
|
||||
2. 恢复 segment desc snapshot。
|
||||
3. 恢复 DMP snapshot。
|
||||
4. 恢复 key_epoch。
|
||||
5. 恢复 dirty bitmap。
|
||||
6. 恢复 mac_table。
|
||||
7. 清除对应 PCKC key。
|
||||
8. desc.state = ACTIVE。
|
||||
```
|
||||
|
||||
### 8.3 System Rollback
|
||||
|
||||
```text
|
||||
1. DRR 写 crash reason。
|
||||
2. 标记 boot attempt failed。
|
||||
3. 触发 reboot。
|
||||
4. bootloader 读取 BCB。
|
||||
5. 如果失败次数超限,切换 last_good_slot。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 任务创建算法
|
||||
|
||||
```text
|
||||
task_create(entry, priority, flags)
|
||||
1. 分配 TCB。
|
||||
2. 生成 tid。
|
||||
3. 生成 process_uuid。
|
||||
4. 创建 utsm_process_context。
|
||||
5. 创建 stack segment。
|
||||
6. 创建 heap segment。
|
||||
7. 可选创建 ipc segment。
|
||||
8. 初始化 capability table。
|
||||
9. cap[0] = stack。
|
||||
10. cap[1] = heap。
|
||||
11. 初始化 CPU context。
|
||||
12. 通过 UTRW_WRITE 写入 task_start_packet。
|
||||
13. hot_segment_hint = stack.segment_slot。
|
||||
14. state = READY。
|
||||
15. enqueue_task(current_cpu)。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 调度切换算法
|
||||
|
||||
```text
|
||||
schedule()
|
||||
1. old = current。
|
||||
2. utsm_switch_out(old)。
|
||||
3. next = pick_next_task()。
|
||||
4. utsm_switch_in(next)。
|
||||
5. context_switch(old, next)。
|
||||
```
|
||||
|
||||
`utsm_switch_out`:
|
||||
|
||||
```text
|
||||
1. 如果 old 有 PWC dirty,登记 flush pending。
|
||||
2. 保存 old.hot_segment_hint。
|
||||
3. 更新 old.recovery_generation。
|
||||
4. 更新 heartbeat。
|
||||
```
|
||||
|
||||
`utsm_switch_in`:
|
||||
|
||||
```text
|
||||
1. 如果 next.state == RECOVERING,跳过。
|
||||
2. PCKC.current_process_uuid = next.crypto.process_uuid。
|
||||
3. PCKC.current_crypto_epoch = next.crypto.crypto_epoch。
|
||||
4. 预热 next.hot_segment_hint。
|
||||
```
|
||||
|
||||
调度路径禁止:
|
||||
|
||||
```text
|
||||
扫描段
|
||||
扫描 capability table
|
||||
计算 MAC
|
||||
写 checkpoint
|
||||
重加密整段
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. 任务异常处理算法
|
||||
|
||||
```text
|
||||
UTRW_DETECT_FAULT(task, segment, error)
|
||||
1. task.fault_segment_slot = segment.slot。
|
||||
2. task.state = FAULTED。
|
||||
3. 从 runqueue 移除。
|
||||
4. 写 DRR fault event。
|
||||
5. DRR 判断:
|
||||
a. 刷新 capability。
|
||||
b. page rollback。
|
||||
c. segment rollback。
|
||||
d. kill task。
|
||||
e. system rollback。
|
||||
```
|
||||
|
||||
任务 kill:
|
||||
|
||||
```text
|
||||
task_kill(task)
|
||||
1. task.state = ZOMBIE。
|
||||
2. 从 runqueue 移除。
|
||||
3. revoke capability table。
|
||||
4. owned segment key_epoch++。
|
||||
5. desc.state = DESTROYED。
|
||||
6. 加入 deferred free。
|
||||
7. 写 TASK_KILL recovery log。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 复杂度总结
|
||||
|
||||
```text
|
||||
段定位:O(1)
|
||||
UTRW 读写:O(n / 64)
|
||||
PCKC 命中:O(1)
|
||||
PCKC miss:O(KDF + key schedule)
|
||||
Dirty 标记:O(1)
|
||||
Checkpoint:O(number_of_dirty_shards + number_of_dirty_pages)
|
||||
A/B metadata 切换:O(1)
|
||||
DRR emergency alloc:O(1)
|
||||
Page rollback:O(1 page)
|
||||
Segment rollback:O(segment_dirty_pages + metadata)
|
||||
调度切换额外成本:O(1)
|
||||
```
|
||||
@@ -0,0 +1,485 @@
|
||||
# UTSM 设计架构记录
|
||||
|
||||
本文记录 Deshab 内核当前 UTSM 相关架构定稿。
|
||||
|
||||
---
|
||||
|
||||
## 1. 架构目标
|
||||
|
||||
UTSM 的目标不是传统强安全隔离,而是在极高权限、极高效率的单地址空间 Ring0 内核中提供一种封缄内存模型。
|
||||
|
||||
核心目标:
|
||||
|
||||
```text
|
||||
所有普通内存可读,但默认是密文。
|
||||
明文读写必须通过 UTRW。
|
||||
UUID 作为进程和内存段的调谐因子。
|
||||
数据区保持连续,避免 UUID 孔洞。
|
||||
DRR 提供 root key、checkpoint、recovery log 和回滚。
|
||||
调度器保持 O(1)。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 总架构模块
|
||||
|
||||
```text
|
||||
Deshab Kernel Core
|
||||
|
||||
SAS-R0-PCQ
|
||||
单地址空间 Ring0 任务模型
|
||||
Per-CPU O(1) 位图调度器
|
||||
|
||||
DRR
|
||||
Dedicated Recovery Root
|
||||
专用恢复根
|
||||
watchdog / root key / checkpoint / recovery log / A-B rollback
|
||||
|
||||
UTSM
|
||||
UUID-Tuned Sealed Memory
|
||||
UUID 调谐封缄内存
|
||||
|
||||
UTRW
|
||||
UTSM Tagged Reader/Writer
|
||||
UTSM 带标记读写器
|
||||
|
||||
DMP
|
||||
Descriptor Meta Page
|
||||
段描述符元页
|
||||
|
||||
PCKC
|
||||
Per-CPU Key Cache
|
||||
每 CPU 密钥缓存
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. UTSM 内存模型
|
||||
|
||||
每个 UTSM 段由两部分组成:
|
||||
|
||||
```text
|
||||
DMP + Cipher Data
|
||||
```
|
||||
|
||||
布局:
|
||||
|
||||
```text
|
||||
+-------------------------------+
|
||||
| DMP: Descriptor Meta Page |
|
||||
+-------------------------------+
|
||||
| Cipher Data Page 0 |
|
||||
+-------------------------------+
|
||||
| Cipher Data Page 1 |
|
||||
+-------------------------------+
|
||||
| Cipher Data Page 2 |
|
||||
+-------------------------------+
|
||||
| ... |
|
||||
+-------------------------------+
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
```text
|
||||
DMP 不属于用户数据。
|
||||
Cipher Data 只存密文。
|
||||
UUID 不插入 Cipher Data。
|
||||
数据区保持连续。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 关键设计替代
|
||||
|
||||
从原始构想到 UTSM v1 的替代关系:
|
||||
|
||||
```text
|
||||
十进制 UUID
|
||||
-> 128-bit 二进制 UUID
|
||||
|
||||
UUID 数字间隔插入内存
|
||||
-> 独立 DMP 元数据页
|
||||
|
||||
UUID 数字位置表
|
||||
-> segment_slot + generation + tweak_seed
|
||||
|
||||
十进制凯撒
|
||||
-> UUID 调谐的 cache-line 流式加密
|
||||
|
||||
每次传统 syscall
|
||||
-> Ring0 fast accessor + PCKC
|
||||
|
||||
写入时避开 UUID
|
||||
-> 连续密文数据区直接写
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 数据结构架构
|
||||
|
||||
### 5.1 uuid128_t
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
uint64_t hi;
|
||||
uint64_t lo;
|
||||
} uuid128_t;
|
||||
```
|
||||
|
||||
### 5.2 utsm_process_context
|
||||
|
||||
```c
|
||||
struct utsm_process_context {
|
||||
uuid128_t process_uuid;
|
||||
uint64_t crypto_epoch;
|
||||
uint64_t recovery_generation;
|
||||
uint32_t capability_table_slot;
|
||||
uint32_t capability_count;
|
||||
uint32_t flags;
|
||||
};
|
||||
```
|
||||
|
||||
### 5.3 utsm_segment_desc
|
||||
|
||||
```c
|
||||
struct utsm_segment_desc {
|
||||
uuid128_t segment_uuid;
|
||||
uuid128_t owner_process_uuid;
|
||||
void *cipher_base;
|
||||
uint64_t cipher_length;
|
||||
void *dmp_base;
|
||||
uint64_t key_epoch;
|
||||
uint64_t tweak_seed;
|
||||
void *dirty_bitmap;
|
||||
void *mac_table;
|
||||
uint32_t generation;
|
||||
uint32_t flags;
|
||||
uint32_t state;
|
||||
uint32_t last_cpu;
|
||||
uint64_t writer_seq;
|
||||
uint64_t checkpoint_generation;
|
||||
};
|
||||
```
|
||||
|
||||
### 5.4 utsm_dmp
|
||||
|
||||
```c
|
||||
struct utsm_dmp {
|
||||
uint64_t magic;
|
||||
uint32_t version;
|
||||
uint32_t segment_slot;
|
||||
uint64_t fast_base;
|
||||
uint64_t fast_limit;
|
||||
uint64_t fast_tweak_seed;
|
||||
uint64_t fast_key_epoch;
|
||||
uint64_t dirty_bitmap_base;
|
||||
uint64_t mac_table_base;
|
||||
uint64_t last_writer_seq;
|
||||
uint32_t last_cpu;
|
||||
uint32_t flags;
|
||||
uint64_t crc;
|
||||
};
|
||||
```
|
||||
|
||||
### 5.5 utsm_capability
|
||||
|
||||
```c
|
||||
struct utsm_capability {
|
||||
uint32_t segment_slot;
|
||||
uint32_t generation;
|
||||
uint32_t rights;
|
||||
uint32_t epoch;
|
||||
uint64_t uuid_digest;
|
||||
uint64_t auth_tag;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. UTRW 读写器架构
|
||||
|
||||
UTRW 分三层:
|
||||
|
||||
```text
|
||||
Level 0: Raw Access
|
||||
直接访问 cipher_base,读到密文。
|
||||
|
||||
Level 1: Fast Path
|
||||
capability O(1) 定位段。
|
||||
PCKC 命中。
|
||||
无全局锁。
|
||||
无 trap。
|
||||
|
||||
Level 2: Slow Path
|
||||
key miss。
|
||||
epoch mismatch。
|
||||
checkpoint/recovery。
|
||||
MAC fail。
|
||||
poisoned segment。
|
||||
```
|
||||
|
||||
读写基本流程:
|
||||
|
||||
```text
|
||||
Read:
|
||||
cap -> segment desc -> PCKC key -> 64B line 解密 -> 返回明文
|
||||
|
||||
Write:
|
||||
cap -> segment desc -> PCKC key -> 64B line 加密 -> 写密文 -> dirty bitmap -> recovery log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. DRR 协作架构
|
||||
|
||||
DRR 保存:
|
||||
|
||||
```text
|
||||
root_key 或 root_key handle
|
||||
global_crypto_epoch
|
||||
segment table snapshot
|
||||
DMP snapshot
|
||||
dirty shard summary
|
||||
dirty bitmap
|
||||
MAC root
|
||||
recovery log
|
||||
poisoned segment list
|
||||
Boot Control Block
|
||||
DRR Emergency Pool
|
||||
A/B checkpoint metadata slot
|
||||
```
|
||||
|
||||
DRR 负责:
|
||||
|
||||
```text
|
||||
watchdog 检测
|
||||
freeze-all
|
||||
checkpoint
|
||||
page rollback
|
||||
segment rollback
|
||||
system rollback
|
||||
A/B 镜像回滚
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Checkpoint / Rollback 架构
|
||||
|
||||
Checkpoint 类型:
|
||||
|
||||
```text
|
||||
Light Checkpoint
|
||||
控制面快照。
|
||||
|
||||
Dirty Page Checkpoint
|
||||
dirty ciphertext page 快照。
|
||||
|
||||
Boot Checkpoint
|
||||
启动状态和 A/B slot 信息。
|
||||
```
|
||||
|
||||
### 8.1 Dirty Shard
|
||||
|
||||
Dirty Bitmap 采用分片结构。
|
||||
|
||||
```text
|
||||
Dirty Shard
|
||||
dirty_count
|
||||
shard_id
|
||||
page_base
|
||||
page_count
|
||||
last_checkpoint_epoch
|
||||
bitmap
|
||||
```
|
||||
|
||||
checkpoint 时:
|
||||
|
||||
```text
|
||||
dirty_count == 0 的 shard 直接跳过。
|
||||
dirty_count > 0 的 shard 才扫描 dirty bit。
|
||||
```
|
||||
|
||||
这样 checkpoint 成本为:
|
||||
|
||||
```text
|
||||
O(number_of_dirty_shards + number_of_dirty_pages)
|
||||
```
|
||||
|
||||
### 8.2 A/B Checkpoint Metadata
|
||||
|
||||
checkpoint metadata 使用双槽:
|
||||
|
||||
```text
|
||||
Checkpoint Metadata Slot A
|
||||
Checkpoint Metadata Slot B
|
||||
```
|
||||
|
||||
写入规则:
|
||||
|
||||
```text
|
||||
写 inactive slot
|
||||
写 metadata / dirty index / MAC root / CRC
|
||||
flush
|
||||
原子切换 active slot
|
||||
旧 slot 作为 fallback
|
||||
```
|
||||
|
||||
恢复规则:
|
||||
|
||||
```text
|
||||
active slot 有效 -> 使用 active
|
||||
active slot 无效 -> fallback 另一个 slot
|
||||
双槽都无效 -> system rollback
|
||||
```
|
||||
|
||||
### 8.3 DRR Emergency Pool
|
||||
|
||||
DRR 独立预留紧急内存池。
|
||||
|
||||
```text
|
||||
DRR Emergency Pool
|
||||
DRR private stack
|
||||
recovery log buffer
|
||||
checkpoint metadata buffer
|
||||
crash buffer
|
||||
metadata slab
|
||||
emergency pages
|
||||
```
|
||||
|
||||
约束:
|
||||
|
||||
```text
|
||||
普通 allocator 不可使用。
|
||||
普通 OOM 不影响 DRR recovery。
|
||||
DRR recovery 路径禁止依赖普通堆分配器。
|
||||
Emergency Pool 耗尽时进入 system rollback。
|
||||
```
|
||||
|
||||
Rollback 级别:
|
||||
|
||||
```text
|
||||
Page Rollback
|
||||
单页恢复。
|
||||
|
||||
Segment Rollback
|
||||
整段恢复。
|
||||
|
||||
System Rollback
|
||||
重启并由 bootloader 切换 last_good_slot。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 与 SAS-R0-PCQ 的整合
|
||||
|
||||
UTSM Task 是:
|
||||
|
||||
```text
|
||||
Ring0 调度实体
|
||||
+ process_uuid
|
||||
+ crypto context
|
||||
+ capability table
|
||||
+ encrypted stack/heap
|
||||
+ PCKC hot hint
|
||||
+ DRR recovery generation
|
||||
```
|
||||
|
||||
调度切换:
|
||||
|
||||
```text
|
||||
schedule()
|
||||
-> utsm_switch_out(old)
|
||||
-> pick_next_task()
|
||||
-> utsm_switch_in(next)
|
||||
-> context_switch(old, next)
|
||||
```
|
||||
|
||||
调度路径只允许:
|
||||
|
||||
```text
|
||||
设置 crypto 指针
|
||||
加载 process_uuid
|
||||
预热 hot_segment_hint
|
||||
标记 PWC dirty flush
|
||||
```
|
||||
|
||||
禁止:
|
||||
|
||||
```text
|
||||
扫描段
|
||||
扫描 capability table
|
||||
计算 MAC
|
||||
写 checkpoint
|
||||
重加密整段
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 启动顺序
|
||||
|
||||
```text
|
||||
Bootloader
|
||||
-> 读取 Boot Control Block
|
||||
-> 选择 active_slot / last_good_slot
|
||||
-> 加载 SYSTEM/boot/utsm.elf
|
||||
-> 传入 memory map 和 DRR region
|
||||
|
||||
DRR Init
|
||||
-> 初始化 watchdog
|
||||
-> 建立 root key handle
|
||||
-> 初始化 recovery log
|
||||
-> 初始化 checkpoint region
|
||||
-> 初始化 heartbeat page
|
||||
-> 初始化 DRR Emergency Pool
|
||||
-> 初始化 A/B checkpoint metadata slot
|
||||
|
||||
UTSM Init
|
||||
-> 初始化 global crypto epoch
|
||||
-> 初始化 segment table
|
||||
-> 初始化 DMP pool
|
||||
-> 初始化 PCKC area
|
||||
-> 初始化 dirty shard pool
|
||||
-> 初始化 dirty bitmap / MAC table pool
|
||||
-> 注册 UTRW fast path / slow path
|
||||
|
||||
Scheduler Init
|
||||
-> 初始化 per-CPU runqueue
|
||||
-> 初始化 per-CPU heartbeat
|
||||
-> 初始化每 CPU PCKC
|
||||
-> 创建 bootstrap task
|
||||
-> 创建核心服务 task
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. 当前定稿边界
|
||||
|
||||
UTSM v1 确定:
|
||||
|
||||
```text
|
||||
加密粒度:64B cache line
|
||||
Dirty 粒度:4KB page
|
||||
Dirty 分片:Dirty Shard
|
||||
MAC 粒度:4KB page
|
||||
段定位:O(1)
|
||||
调度额外成本:O(1)
|
||||
checkpoint 成本:O(dirty shards + dirty pages)
|
||||
checkpoint metadata:A/B 双槽,CRC 校验,原子切换
|
||||
DRR recovery 内存:Emergency Pool 独立预留
|
||||
```
|
||||
|
||||
暂不追求:
|
||||
|
||||
```text
|
||||
完整 RAM 原地回滚
|
||||
对恶意 Ring0 代码的强安全隔离
|
||||
设备外部副作用回滚
|
||||
```
|
||||
|
||||
设备恢复策略:
|
||||
|
||||
```text
|
||||
内存恢复后,设备 reset/reinit。
|
||||
磁盘依赖文件系统 journal。
|
||||
网卡 TX 已发包不回滚,RX/TX ring 重建。
|
||||
```
|
||||
@@ -0,0 +1,461 @@
|
||||
# Deshab 桌面环境架构设计
|
||||
|
||||
## 1. 概述
|
||||
|
||||
Deshab 桌面环境(Deshab Desktop Environment, DDE)是基于 UTSM/DSK 内核的图形桌面系统,
|
||||
运行在 SAS-R0(单地址空间 Ring0)任务模型上,使用 "Sealed Arc" 视觉风格系统。
|
||||
|
||||
**设计原则**:
|
||||
- **SAS-R0 适配**:无内存隔离,所有应用共享地址空间,信任模型为 Ring0 全信任
|
||||
- **单屏幕协作**:初期采用"多窗口前台 + 桌面后台"模式,桌面管理器始终驻留
|
||||
- **应用独立开发**:内置应用使用回调模式;未来工具应用为独立 .elf,通过 ELF 加载方式载入
|
||||
- **帧缓冲直绘**:无 GPU 加速,所有渲染通过 du_context 直接写 framebuffer
|
||||
|
||||
**当前实现状态**:desktop.elf 已实现完整的桌面管理器框架,包括窗口管理、事件路由、
|
||||
PS/2 鼠标初始化+轮询、光标 save/restore、任务栏、桌面图标和 3 个内置应用。
|
||||
|
||||
## 2. 系统架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Framebuffer │
|
||||
│ ┌─────────────────────────────────────────────┐ │
|
||||
│ │ Desktop Manager (desktop.elf) │ │
|
||||
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
|
||||
│ │ │ Window 1 │ │ Window 2 │ │ Window 3 │ │ │
|
||||
│ │ │ (bash) │ │ (editor) │ │ (calc) │ │ │
|
||||
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────────────────────────────┐│ │
|
||||
│ │ │ Taskbar (40px) ││ │
|
||||
│ │ └─────────────────────────────────────────┘│ │
|
||||
│ └─────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 3. 启动流程
|
||||
|
||||
```
|
||||
UEFI → Limine → utsm.elf → DKM 驱动加载
|
||||
→ deshab.elf (DSK) → spinner → firstInit.txt 检查
|
||||
→ mouseInit.elf → netman.elf → [首次] FirstInit.elf
|
||||
→ desktop.elf ← 桌面管理器
|
||||
```
|
||||
|
||||
DSK 在 FirstInit 完成或 firstInit=1 时,加载 `desktop.elf`。
|
||||
desktop.elf 通过 `dsk_entry(dsk_boot_context *ctx)` 入口接收系统上下文,
|
||||
自行初始化 PS/2 鼠标、注册应用、进入主事件循环。
|
||||
|
||||
## 4. Desktop Manager 核心设计
|
||||
|
||||
### 4.1 窗口模型
|
||||
|
||||
```c
|
||||
typedef struct desktop_window {
|
||||
int id; /* 窗口 ID(自增分配) */
|
||||
int x, y, w, h; /* 窗口位置和尺寸 */
|
||||
int visible; /* 可见性 */
|
||||
int focused; /* 焦点 */
|
||||
int minimized; /* 最小化 */
|
||||
char title[48]; /* 窗口标题 */
|
||||
|
||||
/* 应用关联 */
|
||||
int app_id; /* 关联的应用 ID(g_apps 索引) */
|
||||
void *app_state; /* 应用私有状态(on_create 返回值) */
|
||||
int closing; /* 关闭中标记 */
|
||||
int dirty; /* 脏标记(需要重绘) */
|
||||
} desktop_window;
|
||||
```
|
||||
|
||||
**Z 序**:窗口按数组顺序排列,数组末尾的窗口在最上层。`win_bring_to_front()` 将窗口移到数组末尾。
|
||||
|
||||
**窗口限制**:最多 8 个窗口(`MAX_WINDOWS`)。
|
||||
|
||||
**固定地址分配**:当前内置应用使用固定地址分配状态结构,避免堆依赖:
|
||||
- `0x4000000` — bash_state(终端)
|
||||
- `0x5000000` — editor_state(编辑器)
|
||||
- `0x6000000` — calc_state(计算器)
|
||||
|
||||
### 4.2 事件系统
|
||||
|
||||
```c
|
||||
typedef enum {
|
||||
EV_MOUSE_MOVE = 1,
|
||||
EV_MOUSE_DOWN,
|
||||
EV_MOUSE_UP,
|
||||
EV_KEY_DOWN,
|
||||
EV_KEY_UP,
|
||||
} ev_type;
|
||||
|
||||
typedef struct {
|
||||
ev_type type;
|
||||
int mx, my; /* 鼠标全局坐标 */
|
||||
int button; /* 0=左, 1=右 */
|
||||
u8 scancode;
|
||||
int shift, ctrl, alt;
|
||||
} desktop_event;
|
||||
```
|
||||
|
||||
**事件路由**:
|
||||
1. **鼠标事件** → 从后往前命中测试 → 找到目标窗口 → 检查关闭按钮/标题栏/客户区 → 路由到窗口回调
|
||||
2. **键盘事件** → 当前焦点窗口的 `on_event` 回调
|
||||
3. **任务栏点击** → 桌面管理器直接处理(快速启动/窗口按钮)
|
||||
4. **桌面图标点击** → 桌面管理器处理(`launch_app()`)
|
||||
|
||||
**拖拽机制**:
|
||||
- 鼠标按下 + 命中标题栏 → 进入拖拽模式(`g_dragging=1`)
|
||||
- 拖拽期间鼠标移动 → 更新窗口位置(`w->x = mouse_x - offset`)
|
||||
- 鼠标释放 → 退出拖拽模式
|
||||
|
||||
**关闭机制**:
|
||||
- 鼠标点击窗口右上角红色 X 按钮(24×20 圆角矩形,DP_ERROR 底色)
|
||||
- `win_destroy()` 调用应用的 `on_destroy`,从窗口数组移除,焦点转移到最后一个窗口
|
||||
|
||||
### 4.3 应用 ABI(回调模式)
|
||||
|
||||
```c
|
||||
typedef struct app_ctx {
|
||||
du_context *fb; /* 全局帧缓冲渲染上下文 */
|
||||
desktop_win *win; /* 关联窗口 */
|
||||
int client_x, client_y, client_w, client_h; /* 客户区坐标 */
|
||||
int should_exit; /* 退出标志 */
|
||||
desktop_block_read_fn block_read; /* FAT32 块读取函数 */
|
||||
const void *kernel_api; /* DKM kernel_api 分发表 */
|
||||
} app_ctx;
|
||||
|
||||
typedef void *(*app_create_fn)(app_ctx *ctx);
|
||||
typedef void (*app_event_fn)(void *state, app_ctx *ctx, desktop_event *ev);
|
||||
typedef void (*app_draw_fn)(void *state, app_ctx *ctx);
|
||||
typedef void (*app_destroy_fn)(void *state);
|
||||
|
||||
typedef struct {
|
||||
const char *name; /* 应用标识名 */
|
||||
const char *display_name; /* UI 显示名 */
|
||||
u32 default_w, default_h; /* 默认窗口尺寸 */
|
||||
app_create_fn on_create;
|
||||
app_event_fn on_event;
|
||||
app_draw_fn on_draw;
|
||||
app_destroy_fn on_destroy;
|
||||
} app_descriptor;
|
||||
```
|
||||
|
||||
**应用生命周期**:
|
||||
1. 用户点击桌面图标或快速启动 → `launch_app(app_id)`
|
||||
2. 创建窗口 → 构建 `app_ctx` → 调用 `on_create(ctx)` → 返回 `app_state`
|
||||
3. 事件循环中:`on_event(state, ctx, ev)` 处理输入
|
||||
4. 绘制时:`on_draw(state, ctx)` 渲染客户区
|
||||
5. 关闭窗口 → `on_destroy(state)` 清理
|
||||
|
||||
**当前注册的应用**:
|
||||
|
||||
| app_id | name | display_name | 默认尺寸 | 状态 |
|
||||
|--------|------|-------------|----------|------|
|
||||
| 0 | bash | Terminal | 640×440 | 已实现 |
|
||||
| 1 | editor | Editor | 600×450 | 已实现 |
|
||||
| 2 | fileman | Files | 500×400 | 占位(无回调) |
|
||||
| 3 | calc | Calculator | 280×400 | 已实现 |
|
||||
|
||||
### 4.4 任务栏 (Taskbar)
|
||||
|
||||
位置:屏幕底部,高度 40px。
|
||||
|
||||
布局:
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ [D] │ 🖥️ 📝 📁 🧮 │ │ 12:34 │
|
||||
│Start│ 快速启动(4图标) │ 窗口按钮 │ RTC时钟 │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
分区:
|
||||
- **Start 按钮**(48×32,DP_ABYSS_600 圆角矩形):显示 "D" 字符(DS_DARK_ACCENT_LIGHT)
|
||||
- **快速启动**(4 图标 × 40px):按 app_id 顺序绘制程序化图标(终端/编辑器/文件夹/计算器)
|
||||
- **窗口按钮区**:每个打开窗口一个 100×32 按钮,焦点窗口用 DS_DARK_ACCENT 底色,其余用 DP_ABYSS_600
|
||||
- **RTC 时钟**(右侧 80px 区域):通过 CMOS I/O(端口 0x70/0x71)读取 BCD 时分,转换为 HH:MM 格式
|
||||
|
||||
### 4.5 桌面图标
|
||||
|
||||
位置:桌面右侧垂直排列。
|
||||
|
||||
参数:
|
||||
- 列宽 80px(`DESKTOP_ICON_W`),行高 72px(`DESKTOP_ICON_H`)
|
||||
- 左边距 16px(`ICON_GUTTER_X`),上边距 16px(`ICON_GUTTER_Y`)
|
||||
- 起始 X = `fb_width - 80 - 16`
|
||||
|
||||
图标:32×32 像素,程序化生成(无需位图文件),通过 `draw_icon_*` 函数绘制:
|
||||
- **终端图标**:DP_ABYSS_700 圆角矩形 + DP_SEAL_300 的 >_ 符号 + DP_SEAL_500 边框
|
||||
- **编辑器图标**:DP_ABYSS_700 圆角矩形 + DP_SEAL_500 文本行 + DP_SEAL_300 边框
|
||||
- **文件夹图标**:DP_ARC_500 圆角矩形 + DP_ARC_300 文件夹形状 + DP_ARC_700 边框
|
||||
- **计算器图标**:DP_ABYSS_700 圆角矩形 + DP_WARNING 按键 + DP_NEUTRAL_400 网格
|
||||
|
||||
标签:图标下方 36px 处,居中绘制应用 display_name,使用 DS_DARK_TEXT_PRIMARY 颜色。
|
||||
|
||||
### 4.6 窗口装饰
|
||||
|
||||
**标题栏**(28px,`TITLEBAR_H`):
|
||||
- 焦点窗口:DP_ABYSS_600 背景
|
||||
- 非焦点窗口:DP_ABYSS_800 背景
|
||||
- 标题文字:左侧 DU_SPACE_SM 偏移,DS_DARK_TEXT_PRIMARY 颜色
|
||||
- 关闭按钮:右上角,窗口右边 -28px 处,24×20 圆角矩形,DP_ERROR (红色) 底色 + 白色 "X"
|
||||
|
||||
**边框**(2px,`BORDER_W`):
|
||||
- 焦点窗口:DS_DARK_BORDER(Seal Cyan 发光效果)
|
||||
- 非焦点窗口:DS_DARK_BORDER
|
||||
- 焦点发光:`du_rect_glow()` 3px 扩展范围,10px 衰减
|
||||
|
||||
**标题栏底线**:1px 分隔线,颜色同边框色。
|
||||
|
||||
**圆角**:窗口主体使用 `DU_RADIUS_LG` 圆角,关闭按钮使用 `DU_RADIUS_SM` 圆角。
|
||||
|
||||
### 4.7 应用加载模型
|
||||
|
||||
**方式一:回调式(当前实现)**
|
||||
|
||||
应用编译进 desktop.elf 内部,通过 `app_descriptor` 注册回调函数。
|
||||
桌面管理器在事件循环中调用 `on_event()`/`on_draw()`,应用通过 `app_ctx` 访问系统服务。
|
||||
|
||||
特点:
|
||||
- 应用与桌面管理器在同一 ELF 中,共享代码和全局变量
|
||||
- 应用状态使用固定地址分配(避免堆依赖)
|
||||
- 应用可以直接访问 g_fb 全局帧缓冲
|
||||
|
||||
**方式二:独立 ELF 加载式(未来实现)**
|
||||
|
||||
工具应用独立开发为单独 .elf 文件(如 `CODE/tools/bash/`),通过 DSK 的 FAT32 + ELF loader 加载。
|
||||
独立工具实现 `dsk_entry(dsk_boot_context *ctx)` 入口点,接收与 DSK 相同的系统上下文。
|
||||
|
||||
未来桌面管理器将通过 ELF 加载方式载入工具 .elf,需要实现:
|
||||
- ELF 加载到内存 + PIE 重定位
|
||||
- 传入 dsk_boot_context(framebuffer、kernel_api、block_read 等)
|
||||
- 返回机制(在 ELF 入口点保存返回地址)
|
||||
- 独立工具的公共辅助代码(`CODE/tools/desktop_app.h`)
|
||||
|
||||
## 5. 渲染管线
|
||||
|
||||
```
|
||||
redraw_all() 完整管线:
|
||||
1. 渐变背景(du_fill_bg_gradient: DP_ABYSS_900 → DP_ABYSS_800)
|
||||
2. 桌面图标(draw_desktop_icons)
|
||||
3. 窗口循环(从底到顶):
|
||||
a. 应用 on_draw() 绘制客户区内容
|
||||
b. draw_window_frame() 绘制窗口装饰(在应用内容之上)
|
||||
4. 任务栏(draw_taskbar)
|
||||
5. 鼠标光标(cursor_save_bg + cursor_draw)
|
||||
```
|
||||
|
||||
**渲染策略**:
|
||||
- 每帧全屏重绘(无增量更新)
|
||||
- 鼠标光标使用 save/restore 机制:移动前恢复旧位置背景,重绘后保存新位置背景
|
||||
- 应用直接写入全局 framebuffer(无窗口后缓冲),窗口装饰在应用内容之上绘制
|
||||
- 重绘触发:鼠标移动/点击、键盘事件、窗口状态变化
|
||||
|
||||
## 6. 像素格式
|
||||
|
||||
与现有 framebuffer 一致:32bpp ARGB(0xAARRGGBB),小端存储。
|
||||
所有颜色值使用 deshab_ui.h 中的语义色令牌。
|
||||
|
||||
## 7. 鼠标光标
|
||||
|
||||
24×24 像素箭头光标:
|
||||
- 热点在左上角 (0,0)
|
||||
- 形状定义:`cursor_shape[24][24]` 位图数组(1=前景,0=透明)
|
||||
- 前景色:DS_DARK_TEXT_PRIMARY
|
||||
- save/restore 实现无闪烁移动:
|
||||
- `cursor_save_bg()`: 保存光标位置 24×24 像素到 `g_cursor_save[]`
|
||||
- `cursor_restore_bg()`: 恢复上次保存的像素
|
||||
- 每帧重绘时:先 restore 旧位置 → 全屏绘制 → save + draw 新位置
|
||||
- 边界限制:光标不超出屏幕范围(减去 CURSOR_SIZE)
|
||||
|
||||
## 8. 输入处理
|
||||
|
||||
### 8.1 PS/2 鼠标
|
||||
|
||||
**初始化**(`ps2_mouse_init()`):
|
||||
1. 启用 AUX 设备(命令 0xA8 → 0x64)
|
||||
2. 读取控制器配置字节(0x20 → 0x64),设置 bit1(AUX IRQ12)+ 清除 bit5(AUX clock)
|
||||
3. 写回配置(0x60 → 0x64)
|
||||
4. 复位鼠标(0xD4 → 0x64,0xFF → 0x60)
|
||||
5. 启用 streaming(0xD4 → 0x64,0xF4 → 0x60)
|
||||
|
||||
**轮询**(`ps2_mouse_poll()`):
|
||||
- 读取端口 0x64 状态,检查 bit0(数据就绪)和 bit5(AUX 标记)
|
||||
- 读取 0x60 数据,累积 3 字节组成一个鼠标包
|
||||
- 校验 byte0 bit3 同步位
|
||||
- 解析 X/Y 位移(带符号扩展)和左键状态(byte0 bit0)
|
||||
- Y 轴翻转处理(鼠标 Y 向上为正,屏幕 Y 向下为正)
|
||||
- 边界裁剪:光标限制在屏幕范围内
|
||||
|
||||
### 8.2 PS/2 键盘
|
||||
|
||||
- IRQ1 → scan code set 1
|
||||
- 扩展键 E0 前缀追踪(`g_e0` 标记)
|
||||
- Shift 修饰键追踪(0x2A/0x36 按下,0xAA/0xB6 释放)
|
||||
- `scan_to_ascii()` 映射:normal[58] + shifted[58] 查找表
|
||||
- 键盘事件发送到焦点窗口的 `on_event` 回调
|
||||
|
||||
**全局快捷键**(规划中):
|
||||
- Alt+Tab:窗口切换
|
||||
- Alt+F4:关闭窗口
|
||||
|
||||
## 9. 文件系统接口
|
||||
|
||||
工具应用通过 `app_ctx.block_read` 访问 FAT32 文件系统。
|
||||
|
||||
`block_read` 函数类型:
|
||||
```c
|
||||
typedef int (*desktop_block_read_fn)(void *ctx, unsigned long long lba, unsigned int count, void *buffer);
|
||||
```
|
||||
|
||||
从 `dkm_kernel_api + 0xA8` 偏移处获取函数指针。
|
||||
|
||||
暂不实现 VFS 系统调用——所有文件操作通过直接 FAT32 路径解析完成。
|
||||
|
||||
## 10. 网络接口
|
||||
|
||||
网络工具(curl、ping、browser)依赖 netman 已实现的:
|
||||
- DHCP 客户端
|
||||
- ARP 解析
|
||||
- DNS 查询
|
||||
- e1000/virtio_net TX/RX
|
||||
|
||||
工具应用通过 `kernel_api.net` 访问网络功能。
|
||||
|
||||
## 11. 内置应用详情
|
||||
|
||||
### 11.1 终端 (Bash)
|
||||
|
||||
- 状态结构:`bash_state` @ 0x4000000
|
||||
- 终端缓冲:80 列 × 40 行(TERM_MAX_COLS × TERM_MAX_ROWS)
|
||||
- 每格存储:字符(u8) + 前景色(u32)
|
||||
- 输入缓冲:256 字节,支持插入模式和光标移动
|
||||
- 提示符:`deshab# `
|
||||
- 命令:help, clear, echo, version/ver, uname, date, about, reboot, halt, pwd, whoami, id
|
||||
- 渲染:先绘制历史内容,再绘制当前输入行+光标
|
||||
- 光标:2px 高下划线,DS_DARK_CURSOR 颜色
|
||||
- 配色:DS_DARK_* 暗色主题
|
||||
|
||||
### 11.2 文本编辑器 (Editor)
|
||||
|
||||
- 状态结构:`editor_state` @ 0x5000000
|
||||
- 文本缓冲:65536 字节(EDITOR_BUF_SIZE)
|
||||
- 编辑操作:插入/删除字符、换行、方向键移动、Home/End
|
||||
- 行号:3 位数字 + 分隔线(DS_DARK_TEXT_DIM 颜色)
|
||||
- 自动滚动:光标超出可视区域时调整 scroll_y
|
||||
- 状态栏:底部 20px,显示 L:行 C:列 + 修改标记(*)
|
||||
- 光标:2px 宽竖线,DS_DARK_CURSOR 颜色
|
||||
- 编辑区背景:DS_DARK_BG_SECONDARY
|
||||
- 窗口标题:`Editor - untitled`
|
||||
|
||||
### 11.3 计算器 (Calculator)
|
||||
|
||||
- 状态结构:`calc_state` @ 0x6000000
|
||||
- 运算:四则运算(+/-/×/÷),i64 精度
|
||||
- 显示屏:圆角矩形,右对齐数字
|
||||
- 按钮网格:4×5 布局(C/+/-/%/÷, 7/8/9/×, 4/5/6/-, 1/2/3/+, 0/./=)
|
||||
- 按键颜色:功能键 DP_ABYSS_600,运算符 DS_DARK_ACCENT,等号 DP_SUCCESS
|
||||
- 输入:键盘数字键 + 运算符,C 清零,Enter/= 计算
|
||||
|
||||
## 12. 分阶段实现计划
|
||||
|
||||
### Phase 1 — 桌面基础(已完成)
|
||||
- ✅ Desktop Manager 核心框架
|
||||
- ✅ 任务栏 + 时钟 + 桌面图标
|
||||
- ✅ 窗口管理(创建/销毁/移动/焦点/拖拽)
|
||||
- ✅ 事件路由系统
|
||||
- ✅ PS/2 鼠标初始化 + 轮询
|
||||
- ✅ 光标 save/restore
|
||||
- ✅ 终端应用(Bash)
|
||||
- ✅ 文本编辑器(Editor)
|
||||
- ✅ 计算器(Calculator)
|
||||
|
||||
### Phase 2 — 文件操作与独立应用
|
||||
- 工具应用独立开发框架(CODE/tools/ + desktop_app.h)
|
||||
- FAT32 路径解析增强(目录遍历)
|
||||
- 文件管理器(独立 .elf)
|
||||
- 编辑器独立化(从内置 → 独立 tools/editor/)
|
||||
- 文件打开器(关联 .txt → 编辑器)
|
||||
- Ctrl+S 保存(需 FAT32 write API)
|
||||
|
||||
### Phase 3 — 网络
|
||||
- TCP/IP 最小实现(基于 e1000/virtio_net)
|
||||
- ping 工具(ICMP Echo)
|
||||
- curl 工具(HTTP GET)
|
||||
|
||||
### Phase 4 — 高级应用
|
||||
- 浏览器(HTTP + 简单 HTML 渲染)
|
||||
- Bash 增强版(命令历史↑↓、ls、cat、Tab 补全)
|
||||
- 更多系统工具
|
||||
|
||||
## 13. 目录结构
|
||||
|
||||
```
|
||||
CODE/
|
||||
desktop/ 桌面管理器(当前实现)
|
||||
main.c 主循环、事件路由、compositing、3个内置应用
|
||||
linker.ld PIE 链接脚本
|
||||
MAKEFILE 构建脚本(输出 desktop.elf)
|
||||
|
||||
tools/ 独立工具应用(未来实现)
|
||||
desktop_app.h 公共辅助头文件
|
||||
bash/ 独立终端
|
||||
main.c
|
||||
MAKEFILE
|
||||
linker.ld
|
||||
editor/ 独立文本编辑器
|
||||
main.c
|
||||
MAKEFILE
|
||||
linker.ld
|
||||
fileman/ 文件管理器
|
||||
main.c
|
||||
MAKEFILE
|
||||
linker.ld
|
||||
browser/ 浏览器
|
||||
main.c
|
||||
MAKEFILE
|
||||
linker.ld
|
||||
curl/ HTTP 客户端
|
||||
main.c
|
||||
MAKEFILE
|
||||
linker.ld
|
||||
ping/ ICMP 工具
|
||||
main.c
|
||||
MAKEFILE
|
||||
linker.ld
|
||||
```
|
||||
|
||||
## 14. 构建与打包
|
||||
|
||||
### 当前构建
|
||||
|
||||
desktop.elf 编译输出到 `SYSTEM/system/deshab64/desktop.elf`。
|
||||
|
||||
编译参数(与 DSK / shell / FirstInit 一致):
|
||||
```
|
||||
clang -target x86_64-unknown-none -std=c11 -ffreestanding -fno-builtin
|
||||
-fno-stack-protector -fpie -mno-red-zone -mno-sse -mno-sse2
|
||||
-mno-mmx -msoft-float -m64 -Wall -Wextra -I../UTSM/include -O2
|
||||
ld.lld -nostdlib -static -pie -z max-page-size=0x1000 -T linker.ld
|
||||
```
|
||||
|
||||
### 未来工具应用构建
|
||||
|
||||
独立工具 .elf 将输出到 `SYSTEM/system/deshab64/tools/`,构建集成:
|
||||
- 每个工具有独立 MAKEFILE(与 desktop 相同模式)
|
||||
- build.ps1 中添加工具构建步骤
|
||||
- mkfat32.c 中添加工具 .elf 入口
|
||||
|
||||
```
|
||||
SYSTEM/system/deshab64/
|
||||
desktop.elf ← 桌面管理器
|
||||
tools/
|
||||
bash.elf ← 独立终端
|
||||
editor.elf ← 独立文本编辑器
|
||||
fileman.elf ← 文件管理器
|
||||
browser.elf ← 浏览器
|
||||
curl.elf ← HTTP 客户端
|
||||
ping.elf ← ICMP 工具
|
||||
```
|
||||
|
||||
DSK 启动流程:
|
||||
- 首次启动:mouseInit → netman → FirstInit → desktop
|
||||
- 非首次启动:mouseInit → netman → desktop
|
||||
@@ -0,0 +1,528 @@
|
||||
# Deshab 工具应用设计文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
Deshab 工具应用是独立开发、独立编译的 .elf 可执行文件,运行在桌面管理器(Desktop Manager)环境中。
|
||||
每个工具在 `CODE/tools/{name}/` 下拥有独立的 `main.c` + `MAKEFILE` + `linker.ld`,
|
||||
通过 DSK 的 FAT32 + ELF loader 加载,接收 `dsk_boot_context` 系统上下文。
|
||||
|
||||
**核心约束**:
|
||||
- 所有应用运行在 Ring0,单地址空间,无内存隔离
|
||||
- 独立工具通过 `dsk_entry(dsk_boot_context *ctx)` 入口点启动
|
||||
- 工具可以直接访问 framebuffer、PS/2 输入、kernel_api
|
||||
- 网络工具依赖 kernel_api.net,文件工具依赖 FAT32 block_read
|
||||
- 公共辅助代码通过 `CODE/tools/desktop_app.h` 共享
|
||||
|
||||
**开发模式演进**:
|
||||
- **当前阶段**:3 个内置应用(Bash/Editor/Calculator)使用回调模式编译在 desktop.elf 内
|
||||
- **目标阶段**:工具应用独立开发为单独 .elf,桌面管理器通过 ELF 加载方式载入
|
||||
|
||||
## 2. 应用 ABI
|
||||
|
||||
### 2.1 独立工具入口
|
||||
|
||||
独立工具 .elf 实现以下入口点:
|
||||
|
||||
```c
|
||||
__attribute__((visibility("default")))
|
||||
void dsk_entry(const dsk_boot_context *ctx);
|
||||
```
|
||||
|
||||
工具接收完整的 `dsk_boot_context`,包含:
|
||||
|
||||
```c
|
||||
typedef struct dsk_boot_context {
|
||||
u64 magic; /* 0x44534B31424F4F54 ("DSK1BOOT") */
|
||||
u32 abi_version; /* 1 */
|
||||
u32 size;
|
||||
|
||||
u64 flags;
|
||||
u64 hhdm_offset;
|
||||
u64 rsdp_address;
|
||||
|
||||
u64 framebuffer_address; /* 帧缓冲物理地址 (+ HHDM) */
|
||||
u64 framebuffer_width;
|
||||
u64 framebuffer_height;
|
||||
u64 framebuffer_pitch;
|
||||
u32 framebuffer_bpp;
|
||||
|
||||
u64 boot_modules_response;
|
||||
u64 dkm_kernel_api; /* DKM kernel_api 分发表 */
|
||||
u64 dkm_driver_table;
|
||||
u64 dkm_driver_count;
|
||||
|
||||
u64 utsm_state;
|
||||
u64 drr_state;
|
||||
u64 memory_map;
|
||||
u64 memory_map_count;
|
||||
u64 memory_map_entry_size;
|
||||
u64 kernel_stack_top;
|
||||
} dsk_boot_context;
|
||||
```
|
||||
|
||||
### 2.2 公共辅助头文件
|
||||
|
||||
`CODE/tools/desktop_app.h` 提供所有工具共享的定义和辅助函数:
|
||||
|
||||
```c
|
||||
/* 类型定义 */
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
typedef long long i64;
|
||||
|
||||
/* COM1 串口日志 */
|
||||
#define COM1 0x3F8
|
||||
static inline void outb(u16 port, u8 value);
|
||||
static inline u8 inb(u16 port);
|
||||
void sputc(char c);
|
||||
void swrite(const char *s);
|
||||
void slog(const char *s);
|
||||
|
||||
/* PS/2 键盘轮询 */
|
||||
int ps2kbd_poll(u8 *scancode); /* 返回 1=有数据 */
|
||||
|
||||
/* PS/2 鼠标轮询 */
|
||||
int ps2mouse_poll(int *dx, int *dy, int *btn); /* 返回 1=有数据包 */
|
||||
|
||||
/* scan code set 1 → ASCII 映射 */
|
||||
char scan_to_ascii(u8 sc, int shift);
|
||||
|
||||
/* 帧缓冲绘制辅助 */
|
||||
void fb_init(u64 addr, u64 w, u64 h, u64 pitch);
|
||||
void fb_pixel(int x, int y, u32 color);
|
||||
void fb_rect(int x, int y, int w, int h, u32 color);
|
||||
void fb_string(const char *s, int x, int y, u32 fg, u32 bg, int step);
|
||||
|
||||
/* FAT32 文件读取辅助 */
|
||||
typedef int (*block_read_fn)(u32 index, u64 lba, u32 count, void *buf);
|
||||
int fat32_read_file(block_read_fn br, const char *path, u8 **data, u32 *size);
|
||||
|
||||
/* 窗口概念(标题栏+关闭按钮+客户区) */
|
||||
#define WIN_TITLEBAR_H 28
|
||||
#define WIN_BORDER_W 2
|
||||
void win_draw_frame(int x, int y, int w, int h, const char *title, int focused);
|
||||
int win_hit_close(int wx, int wy, int ww, int wh, int mx, int my);
|
||||
```
|
||||
|
||||
### 2.3 当前内置应用 ABI(回调模式)
|
||||
|
||||
当前 3 个内置应用编译在 desktop.elf 内,使用回调模式:
|
||||
|
||||
```c
|
||||
typedef struct app_ctx {
|
||||
du_context *fb; /* 全局帧缓冲渲染上下文 */
|
||||
desktop_win *win; /* 关联窗口 */
|
||||
int client_x, client_y, client_w, client_h; /* 客户区坐标 */
|
||||
int should_exit; /* 退出标志 */
|
||||
desktop_block_read_fn block_read; /* FAT32 块读取函数 */
|
||||
const void *kernel_api; /* DKM kernel_api 分发表 */
|
||||
} app_ctx;
|
||||
|
||||
typedef void *(*app_create_fn)(app_ctx *ctx);
|
||||
typedef void (*app_event_fn)(void *state, app_ctx *ctx, desktop_event *ev);
|
||||
typedef void (*app_draw_fn)(void *state, app_ctx *ctx);
|
||||
typedef void (*app_destroy_fn)(void *state);
|
||||
```
|
||||
|
||||
### 2.4 应用生命周期
|
||||
|
||||
**回调式(当前)**:
|
||||
```
|
||||
1. 用户点击图标/快速启动按钮
|
||||
2. 桌面管理器创建窗口
|
||||
3. 桌面调用 app->on_create(ctx) → 返回 app_state
|
||||
4. 事件循环:桌面调用 app->on_event(app_state, ctx, ev)
|
||||
5. 绘制:桌面调用 app->on_draw(app_state, ctx)
|
||||
6. 用户关闭窗口 → 桌面调用 app->on_destroy(app_state)
|
||||
7. 桌面销毁窗口,回收资源
|
||||
```
|
||||
|
||||
**独立 ELF 式(未来)**:
|
||||
```
|
||||
1. 桌面管理器通过 FAT32 读取工具 .elf
|
||||
2. PIE ELF loader 加载 + 重定位
|
||||
3. 调用 dsk_entry(ctx)
|
||||
4. 工具自行接管输入/渲染/主循环
|
||||
5. 工具返回 → 桌面管理器恢复控制
|
||||
```
|
||||
|
||||
## 3. 工具应用详细设计
|
||||
|
||||
### 3.1 终端 (Bash) — CODE/tools/bash/
|
||||
|
||||
**状态**:内置版本已实现(回调模式);独立版本待开发
|
||||
|
||||
**功能**:
|
||||
- 接收 dsk_boot_context,全屏暗色终端
|
||||
- PS/2 键盘输入,命令历史(↑↓键)
|
||||
- 内置命令:help, clear, echo, version/ver, uname, date, about, reboot, halt, pwd, whoami, id, ls, cat
|
||||
- Sealed Arc 暗色主题(DS_DARK_* 色系)
|
||||
|
||||
**UI 设计**:
|
||||
```
|
||||
┌─ deshab# ────────────────────────────[✕]─┐
|
||||
│ deshab# echo "Hello, Deshab!" │
|
||||
│ Hello, Deshab! │
|
||||
│ deshab# _ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
├──────────────────────────────────────────┤
|
||||
│ / 12:34 │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**独立版本结构**:
|
||||
- 标题栏:`deshab#` 标题 + 右侧红色 X 关闭按钮
|
||||
- 主区域:暗色终端输出区 + 当前输入行 + 闪烁光标
|
||||
- 状态栏(底部 20px):左侧当前目录 `/`,右侧 RTC 时间
|
||||
|
||||
**数据结构**:
|
||||
```c
|
||||
typedef struct {
|
||||
u8 ch[TERM_MAX_CHARS]; /* 字符缓冲 */
|
||||
u32 fg[TERM_MAX_CHARS]; /* 前景色缓冲 */
|
||||
int cols, rows; /* 终端尺寸 */
|
||||
int cur_col, cur_row; /* 当前光标位置 */
|
||||
char input_buf[256]; /* 当前输入行 */
|
||||
int input_len, input_cursor; /* 输入长度和光标 */
|
||||
int prompt_len; /* 提示符长度 */
|
||||
char history[16][256]; /* 命令历史 */
|
||||
int history_count; /* 历史条数 */
|
||||
int history_pos; /* 历史浏览位置 */
|
||||
} bash_state;
|
||||
```
|
||||
|
||||
**命令实现**:
|
||||
|
||||
| 命令 | 功能 | 依赖 |
|
||||
|------|------|------|
|
||||
| help | 显示可用命令列表 | 无 |
|
||||
| clear | 清屏 | 无 |
|
||||
| echo | 回显参数 | 无 |
|
||||
| version / ver | 显示版本 "Deshab OS v0.1.0" | 无 |
|
||||
| uname | 显示系统名 "Deshab" | 无 |
|
||||
| date | 显示 RTC 日期时间 | CMOS |
|
||||
| about | 显示系统信息 | 无 |
|
||||
| reboot | 重启(0x64→0xFE) | 键盘控制器 |
|
||||
| halt | 停机(HLT) | 无 |
|
||||
| pwd | 显示当前目录 "/" | 无 |
|
||||
| whoami | 显示 "root" | 无 |
|
||||
| id | 显示 "uid=0(root) gid=0(root)" | 无 |
|
||||
| ls | 列出目录内容 | FAT32 增强遍历 |
|
||||
| cat | 显示文件内容 | FAT32 读取 |
|
||||
|
||||
---
|
||||
|
||||
### 3.2 文本编辑器 (Editor) — CODE/tools/editor/
|
||||
|
||||
**状态**:内置版本已实现(回调模式);独立版本待开发
|
||||
|
||||
**功能**:
|
||||
- 全屏编辑器,行号 + 编辑区 + 状态栏
|
||||
- FAT32 文件打开(通过 kernel_api block_read)
|
||||
- 编辑操作:插入/删除字符、换行、光标移动(方向键/Home/End)
|
||||
- PageUp/PageDown 翻页
|
||||
- 文本选择:Shift+方向键
|
||||
- Ctrl+S 保存(需 FAT32 write API)
|
||||
- 状态栏:行:列、文件名、修改标记
|
||||
|
||||
**UI 设计**:
|
||||
```
|
||||
┌─ Editor — README.TXT ───────────────[✕]─┐
|
||||
│ 1│ # Deshab OS │
|
||||
│ 2│ 单地址空间 Ring0 内核实验系统 │
|
||||
│ 3│ │
|
||||
│ 4│ ## 概述 │
|
||||
│ 5│ Deshab 是一个...█ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
├───┴──────────────────────────────────────┤
|
||||
│ L:5 C:15 README.TXT * │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**数据结构**:
|
||||
```c
|
||||
typedef struct {
|
||||
char text[EDITOR_BUF_SIZE]; /* 文本缓冲 (64KB) */
|
||||
int text_len; /* 文本长度 */
|
||||
int cursor_pos; /* 光标位置(字节偏移) */
|
||||
int scroll_y; /* 垂直滚动偏移(行数) */
|
||||
int cursor_line; /* 光标行号 */
|
||||
int cursor_col; /* 光标列号 */
|
||||
int sel_start, sel_end; /* 选择范围 */
|
||||
int modified; /* 修改标记 */
|
||||
char filename[128]; /* 当前文件名 */
|
||||
} editor_state;
|
||||
```
|
||||
|
||||
**渲染细节**:
|
||||
- 行号:3 位数字宽度(`DS_DARK_TEXT_DIM` 颜色)+ 1px 分隔线(`DS_DARK_DIVIDER`)
|
||||
- 编辑区背景:`DS_DARK_BG_SECONDARY`
|
||||
- 光标:2px 宽竖线,`DS_DARK_CURSOR` 颜色
|
||||
- 状态栏:底部 20px,`DP_ABYSS_800` 背景,显示 `L:行 C:列 文件名 *修改标记`
|
||||
|
||||
---
|
||||
|
||||
### 3.3 文件管理器 (FileManager) — CODE/tools/fileman/
|
||||
|
||||
**状态**:占位(当前 desktop.elf 中 fileman 无回调);独立版本待开发
|
||||
|
||||
**功能**:
|
||||
- 双栏布局:左侧目录树、右侧文件列表
|
||||
- FAT32 目录遍历(需增强到子目录)
|
||||
- 文件图标区分:目录/ELF/TXT/CONF
|
||||
- 双击打开:.txt/.conf → 编辑器,.elf → 执行
|
||||
- 路径栏 + 返回按钮
|
||||
|
||||
**UI 设计**:
|
||||
```
|
||||
┌─ 文件管理器 ────────────────────────[✕]─┐
|
||||
│ [←] /system/deshab64/ │
|
||||
├──────────┬───────────────────────────────┤
|
||||
│ / │ 📁 tools/ DIR │
|
||||
│ /system │ 📄 desktop.elf 53KB ELF │
|
||||
│ /driver │ 📄 editor.elf 28KB ELF │
|
||||
│ │ 📄 deshab.elf 131KB ELF │
|
||||
│ │ 📄 README.TXT 2KB TXT │
|
||||
│ │ 📄 user.conf 1KB CONF │
|
||||
├──────────┴───────────────────────────────┤
|
||||
│ 6 项 │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**文件图标颜色**:
|
||||
|
||||
| 类型 | 图标 | 主色调 |
|
||||
|------|------|--------|
|
||||
| 目录 | 📁 | DP_ARC_500 (紫) |
|
||||
| ELF | 📄 + 可执行标记 | DP_SEAL_300 (青) |
|
||||
| TXT | 📄 + 文本标记 | DP_NEUTRAL_300 (灰) |
|
||||
| CONF | 📄 + 齿轮标记 | DP_WARNING (琥珀) |
|
||||
|
||||
**依赖**:FAT32 子目录遍历(当前 DSK 仅支持根目录读取,需增强)
|
||||
|
||||
---
|
||||
|
||||
### 3.4 浏览器 (Browser) — CODE/tools/browser/
|
||||
|
||||
**状态**:Phase 4 实现(依赖 TCP/IP + HTTP + HTML 渲染)
|
||||
|
||||
**功能**:
|
||||
- 地址栏 + 导航按钮(后退/前进/刷新)
|
||||
- HTTP GET 请求(通过 kernel_api.net)
|
||||
- 简单 HTML 渲染:标题、段落、链接、列表
|
||||
- 超链接点击导航
|
||||
- 历史记录(后退/前进栈)
|
||||
|
||||
**UI 设计**:
|
||||
```
|
||||
┌─ 浏览器 ────────────────────────────[✕]─┐
|
||||
│ [←][→][↻] [http://example.com ][Go] │
|
||||
├──────────────────────────────────────────┤
|
||||
│ Example Domain │
|
||||
│ │
|
||||
│ This domain is for use in illustrative │
|
||||
│ examples in documents. You may use this │
|
||||
│ domain in literature... │
|
||||
│ │
|
||||
│ More information... │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**依赖**:
|
||||
- TCP/IP 栈(需实现 TCP 连接、发送/接收、拥塞控制)
|
||||
- HTTP/1.1 客户端(GET 请求、响应解析)
|
||||
- DNS 解析(netman 已实现)
|
||||
- HTML 解析器(简化版,仅处理常见标签)
|
||||
|
||||
---
|
||||
|
||||
### 3.5 HTTP 客户端 (curl) — CODE/tools/curl/
|
||||
|
||||
**状态**:Phase 3 实现(依赖 TCP/IP 最小实现)
|
||||
|
||||
**功能**:
|
||||
- 命令行界面运行(终端风格)
|
||||
- HTTP GET/HEAD 请求
|
||||
- URL 解析(host:port/path)
|
||||
- 响应头显示(`-i` 选项)
|
||||
- 超时处理
|
||||
|
||||
**命令行**:
|
||||
```
|
||||
curl http://example.com
|
||||
curl -i http://example.com
|
||||
curl --head http://example.com
|
||||
```
|
||||
|
||||
**UI 设计**:
|
||||
```
|
||||
┌─ curl ──────────────────────────────[✕]─┐
|
||||
│ > curl http://example.com │
|
||||
│ HTTP/1.1 200 OK │
|
||||
│ Content-Type: text/html │
|
||||
│ │
|
||||
│ <!doctype html> │
|
||||
│ <html> │
|
||||
│ ... │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**依赖**:TCP/IP 栈 + DNS 解析
|
||||
|
||||
**实现方式**:作为窗口化终端风格应用运行,输出 HTTP 响应内容。
|
||||
|
||||
---
|
||||
|
||||
### 3.6 ICMP 工具 (ping) — CODE/tools/ping/
|
||||
|
||||
**状态**:Phase 3 实现(依赖 ICMP + ARP)
|
||||
|
||||
**功能**:
|
||||
- 发送 ICMP Echo Request
|
||||
- 接收 ICMP Echo Reply
|
||||
- RTT 计算(基于 PIT 已校准计时器)
|
||||
- 统计信息显示(发送/接收/丢包率/平均 RTT)
|
||||
|
||||
**命令行**:
|
||||
```
|
||||
ping 192.168.1.1
|
||||
ping -c 4 10.0.2.2
|
||||
```
|
||||
|
||||
**UI 设计**:
|
||||
```
|
||||
┌─ ping ──────────────────────────────[✕]─┐
|
||||
│ PING 192.168.1.1 │
|
||||
│ 64 bytes: seq=0 time=2ms │
|
||||
│ 64 bytes: seq=1 time=1ms │
|
||||
│ 64 bytes: seq=2 time=3ms │
|
||||
│ │
|
||||
│ --- 192.168.1.1 ping statistics --- │
|
||||
│ 3 packets transmitted, 3 received, 0% │
|
||||
│ RTT min/avg/max = 1/2/3 ms │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**依赖**:
|
||||
- ICMP 协议实现(需通过 kernel_api.net 发送原始 IP 包)
|
||||
- ARP 解析(netman 已实现)
|
||||
- 计时器(PIT 已校准)
|
||||
|
||||
---
|
||||
|
||||
### 3.7 更多应用(规划中)
|
||||
|
||||
| 应用 | 描述 | Phase | 依赖 |
|
||||
|------|------|-------|------|
|
||||
| System Monitor | CPU/内存/网络状态 | 2 | kernel_api |
|
||||
| Paint | 简单绘图工具 | 2 | 无 |
|
||||
| Settings | 系统偏好设置 | 2 | FAT32 write |
|
||||
| Screenshot | 屏幕截图保存 | 3 | FAT32 write |
|
||||
| Music Player | PC 喇叭/AC97 音频 | 4 | 音频驱动 |
|
||||
|
||||
## 4. 依赖矩阵
|
||||
|
||||
```
|
||||
FAT32 Read | FAT32 Write | TCP/IP | ICMP | DNS | ARP | PS/2输入
|
||||
bash ✓ | | | | | | ✓
|
||||
editor ✓ | (保存) | | | | | ✓
|
||||
fileman ✓ | | | | | | ✓
|
||||
browser ✓ | | ✓ | | ✓ | ✓ | ✓
|
||||
curl ✓ | | ✓ | | ✓ | ✓ | ✓
|
||||
ping ✓ | | | ✓ | | ✓ | ✓
|
||||
calculator | | | | | | | ✓
|
||||
```
|
||||
|
||||
## 5. 应用图标设计
|
||||
|
||||
每个应用使用 32×32 像素图标,程序化生成(C 函数绘制,无需位图文件)。
|
||||
|
||||
| 应用 | 图标描述 | 主色调 | 绘制函数 |
|
||||
|------|----------|--------|----------|
|
||||
| bash | 终端窗口 >_ | DP_SEAL_300 (亮青) | `draw_icon_terminal()` |
|
||||
| editor | 笔记本+文本行 | DP_SEAL_500 (青) | `draw_icon_editor()` |
|
||||
| fileman | 文件夹 | DP_ARC_500 (紫) | `draw_icon_folder()` |
|
||||
| calculator | 计算器按键 | DP_WARNING (琥珀) | `draw_icon_calc()` |
|
||||
| browser | 地球/指南针 | DP_SEAL_300 (亮青) | 待实现 |
|
||||
| curl | 箭头+网络 | DP_SEAL_700 (深青) | 待实现 |
|
||||
| ping | 信号波 | DP_SUCCESS (绿) | 待实现 |
|
||||
|
||||
**图标绘制规范**:
|
||||
- 圆角矩形背景(6px 圆角,`DU_RADIUS_SM`)
|
||||
- 1px 描边(使用边框色)
|
||||
- 前景图形使用应用主色调
|
||||
- 背景色:DP_ABYSS_700
|
||||
|
||||
## 6. 构建集成
|
||||
|
||||
### 6.1 独立工具 MAKEFILE
|
||||
|
||||
每个工具有独立的 MAKEFILE(与 desktop.elf 相同模式):
|
||||
|
||||
```makefile
|
||||
# tools/bash/MAKEFILE 示例
|
||||
CC := clang
|
||||
LD := ld.lld
|
||||
|
||||
ROOT := ../../..
|
||||
OUT := $(ROOT)/SYSTEM/system/deshab64/tools/bash.elf
|
||||
|
||||
CFLAGS := -target x86_64-unknown-none -std=c11 -ffreestanding -fno-builtin \
|
||||
-fno-stack-protector -fpie -mno-red-zone -mno-sse -mno-sse2 \
|
||||
-mno-mmx -msoft-float -m64 -Wall -Wextra -I.. -I../../UTSM/include -O2
|
||||
LDFLAGS := -nostdlib -static -pie -z max-page-size=0x1000 -T linker.ld
|
||||
|
||||
C_SOURCES := main.c
|
||||
OBJECTS := $(C_SOURCES:.c=.o)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT)
|
||||
|
||||
$(OUT): $(OBJECTS) linker.ld
|
||||
@if not exist "$(ROOT)\SYSTEM\system\deshab64\tools" mkdir "$(ROOT)\SYSTEM\system\deshab64\tools"
|
||||
$(LD) $(LDFLAGS) -o $@ $(OBJECTS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
```
|
||||
|
||||
### 6.2 build.ps1 集成
|
||||
|
||||
在 `build.ps1` 中添加工具构建步骤:
|
||||
|
||||
```powershell
|
||||
# 构建工具应用
|
||||
$tools = @("bash", "editor", "fileman", "curl", "ping", "browser")
|
||||
foreach ($tool in $tools) {
|
||||
Push-Location "CODE/tools/$tool"
|
||||
& make -f MAKEFILE
|
||||
Pop-Location
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 FAT32 镜像更新
|
||||
|
||||
`mkfat32.c` 中添加工具 .elf 入口:
|
||||
|
||||
```
|
||||
SYSTEM/system/deshab64/tools/bash.elf
|
||||
SYSTEM/system/deshab64/tools/editor.elf
|
||||
SYSTEM/system/deshab64/tools/fileman.elf
|
||||
SYSTEM/system/deshab64/tools/curl.elf
|
||||
SYSTEM/system/deshab64/tools/ping.elf
|
||||
SYSTEM/system/deshab64/tools/browser.elf
|
||||
```
|
||||
|
||||
## 7. 测试策略
|
||||
|
||||
- **单元测试**:每个应用的事件处理回调可用模拟事件测试
|
||||
- **QEMU 集成测试**:完整的启动→桌面→打开应用→操作→关闭流程
|
||||
- **串口日志**:所有应用通过 COM1 输出调试信息(`[bash]`、`[editor]` 等前缀)
|
||||
- **FAT32 验证**:使用 `driver/test.fat32` 测试镜像验证文件读取功能
|
||||
- **独立工具验证**:DSK 直接加载工具 .elf,检查 dsk_entry 入口调用和上下文传递
|
||||
@@ -0,0 +1,38 @@
|
||||
# Deshab 测试用例矩阵
|
||||
|
||||
本目录组织 Deshab-OS 的系统化测试用例文档。
|
||||
|
||||
## 测试矩阵总览
|
||||
|
||||
| 文档 | 范围 | 优先级 |
|
||||
|---|---|---|
|
||||
| [boot-regression.md](boot-regression.md) | 启动链路回归(首启/正常/dev_mode/无盘/无NIC) | P0 |
|
||||
| [linux-compat.md](linux-compat.md) | UTSM+Linux 双内核兼容层端到端 | P0 |
|
||||
| [pe-compat.md](pe-compat.md) | PE/EXE 兼容层(PE32+ native + PE32 x86emu32) | P1 |
|
||||
| [driver-matrix.md](driver-matrix.md) | 14 DKM 驱动功能矩阵 | P1 |
|
||||
| [userapps-matrix.md](userapps-matrix.md) | 用户态程序矩阵(shell/cmd/desktop/tools) | P1 |
|
||||
| [network-e2e.md](network-e2e.md) | 网络端到端(DHCP/ARP/DNS/ping/curl) | P1 |
|
||||
| [performance-baseline.md](performance-baseline.md) | 性能基线(TSC 测量) | P2 |
|
||||
| [x86emu32-coverage.md](x86emu32-coverage.md) | x86emu32 指令覆盖率 | P2 |
|
||||
|
||||
## 测试场景状态标记
|
||||
|
||||
- ✅ PASS: 全部测试项通过
|
||||
- 🔶 PARTIAL: 部分测试项通过,存在已知限制
|
||||
- ❌ FAIL: 关键测试项失败,需修复
|
||||
- ⬜ PENDING: 未执行
|
||||
- ⏭ SKIP: 因环境/依赖不可用而跳过
|
||||
|
||||
## 自动化执行
|
||||
|
||||
```powershell
|
||||
# 运行全部自动化测试场景
|
||||
.\ISO\run_tests.bat
|
||||
|
||||
# 输出
|
||||
# ISO/logs/test-report-<timestamp>.md
|
||||
```
|
||||
|
||||
## Bug 跟踪
|
||||
|
||||
所有测试发现的 bug 登记到 [../Bug记录.txt](../Bug记录.txt),并在对应测试文档中引用 bug 编号。
|
||||
@@ -0,0 +1,96 @@
|
||||
# 启动链路回归测试矩阵
|
||||
|
||||
> 对应计划 Phase C2:验证不同启动场景下系统行为正确
|
||||
|
||||
## 状态: ⬜ PENDING
|
||||
|
||||
## 测试场景
|
||||
|
||||
| # | 场景 | firstInit.txt | 配置 | 期望串口锚点 | 状态 | Bug# |
|
||||
|---|---|---|---|---|---|---|
|
||||
| B1 | 首次启动 | `0\n0` | 空 user.conf | `[DSK] firstInit=0` → `mouseInit` → `FirstInit` → 完成向导 → 写盘 | ⬜ | |
|
||||
| B2 | 正常启动 | `1\n0` | 已有 user.conf | `[DSK] firstInit=1` → `login` → desktop | ⬜ | |
|
||||
| B3 | dev_mode | `1\n1` | dev_mode=1 | `[DSK] dev_mode` → shell run_dev_tests 全绿 → Esc → 正常流程 | ⬜ | |
|
||||
| B4 | 无 SATA 盘 | 任意 | 移除 sata_fat32_dsk.img | DSK fallback 到 Limine module | ⬜ | |
|
||||
| B5 | 无 NIC | 任意 | 移除 `-netdev` | e1000 not found → netman 警告 → 继续启动 | ⬜ | |
|
||||
| B6 | Linux 兼容层启用 | 任意 | +linux-bzImage +linux-initrd | UTSM VMM + Linux park → DSK 正常接管 | ⬜ | |
|
||||
|
||||
## 串口日志锚点(标准启动)
|
||||
|
||||
### 首次启动(B1)
|
||||
|
||||
```
|
||||
[UTSM] boot
|
||||
[UTSM] SELFTEST PASS
|
||||
[UTSM] loading DSK
|
||||
[DSK] boot
|
||||
[DSK] context ok
|
||||
[DSK] firstInit=0
|
||||
[DSK] loading mouseInit.elf
|
||||
[DSK] loading FirstInit.elf
|
||||
[FirstInit] ...
|
||||
[DSK] writing firstInit=1
|
||||
[DSK] loading shell.elf
|
||||
```
|
||||
|
||||
### 正常启动(B2)
|
||||
|
||||
```
|
||||
[UTSM] boot
|
||||
[UTSM] SELFTEST PASS
|
||||
[UTSM] loading DSK
|
||||
[DSK] boot
|
||||
[DSK] firstInit=1
|
||||
[DSK] loading login.elf
|
||||
[DSK] loading desktop.elf
|
||||
```
|
||||
|
||||
### dev_mode(B3)
|
||||
|
||||
```
|
||||
[UTSM] boot
|
||||
[UTSM] SELFTEST PASS
|
||||
[DSK] dev_mode=1
|
||||
[DSK] loading shell.elf
|
||||
[shell] run_dev_tests:
|
||||
[shell] ls: OK
|
||||
[shell] echo>: OK
|
||||
[shell] cat: OK
|
||||
[shell] cp: OK
|
||||
[shell] mv: OK
|
||||
[shell] rm: OK
|
||||
[shell] dev_tests done
|
||||
... (Esc 返回后正常流程)
|
||||
```
|
||||
|
||||
## 自动化脚本
|
||||
|
||||
[ISO/run_qemu_scenario.bat](../../ISO/run_qemu_scenario.bat) 接收场景名参数:
|
||||
|
||||
```powershell
|
||||
.\ISO\run_qemu_scenario.bat firstboot
|
||||
.\ISO\run_qemu_scenario.bat normal
|
||||
.\ISO\run_qemu_scenario.bat devmode
|
||||
.\ISO\run_qemu_scenario.bat nosata
|
||||
.\ISO\run_qemu_scenario.bat nonic
|
||||
.\ISO\run_qemu_scenario.bat linux
|
||||
```
|
||||
|
||||
每个场景输出独立日志到 `ISO/logs/<scenario>-<timestamp>.log`。
|
||||
|
||||
## 配置文件准备
|
||||
|
||||
### B1 首次启动
|
||||
|
||||
- `SYSTEM/system/user/use/firstInit.txt`: `0\n0`
|
||||
- 备份 `user.conf` 后清空内容(仅保留 `DESHAB_USERCONF_V1` 头)
|
||||
|
||||
### B3 dev_mode
|
||||
|
||||
- `firstInit.txt`: `1\n1`
|
||||
- 保持现有 user.conf
|
||||
|
||||
### B4 无 SATA
|
||||
|
||||
- 临时重命名 `.build_tmp/sata_fat32_dsk.img` → `.build_tmp/sata_fat32_dsk.img.bak`
|
||||
- run_qemu.bat 自动检测,缺失时跳过 `-device ide-hd`
|
||||
@@ -0,0 +1,70 @@
|
||||
# 14 DKM 驱动功能矩阵
|
||||
|
||||
> 对应计划 Phase C3:每个驱动的加载、探测、功能验证点
|
||||
|
||||
## 状态: ⬜ PENDING
|
||||
|
||||
## 驱动清单
|
||||
|
||||
| # | 驱动 | stage | class | required | QEMU 参数 | 期望串口日志 | 功能验证点 | 状态 | Bug# |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| 1 | timer | 0 | timer | ✅ | 默认 | `[DKM:timer]` | 100ms busy-wait 精度 | ⬜ | |
|
||||
| 2 | apic | 0 | interrupt | ✅ | 默认 | `[DKM:apic] MADT found` | LAPIC MMIO 只读 | ⬜ | |
|
||||
| 3 | acpi | 0 | platform | ❌ | 默认 | `[DKM:acpi]` | RSDP/XSDT 枚举 | ⬜ | |
|
||||
| 4 | pci | 0 | bus | ✅ | 默认 | `[DKM:pci]` | PCI config space 扫描 | ⬜ | |
|
||||
| 5 | console_fb | 1 | console | ❌ | 默认 | `[DKM:console_fb]` | 淡蓝色背景清屏 | ⬜ | |
|
||||
| 6 | ahci | 1 | storage | ❌ | +SATA 测试盘 | `[DKM:ahci] ahci0 registered` | LBA0 读取 | ⬜ | |
|
||||
| 7 | nvme | 1 | storage | ❌ | `-device nvme` | `[DKM:nvme] 1b36:0010 found` | BAR0 读取(高位 MMIO 未解决则 SKIP) | ⏭ | |
|
||||
| 8 | bootfs | 1 | fs | ✅ | 默认 | `[DKM:bootfs]` | Limine boot module FS | ⬜ | |
|
||||
| 9 | vfs | 2 | fs-core | ✅ | 默认 | `[DKM:vfs]` | 挂载 bootfs | ⬜ | |
|
||||
| 10 | fat32 | 2 | fs | ❌ | +SATA 测试盘 | `[DKM:fat32]` | BPB/FAT/目录项解析 | ⬜ | |
|
||||
| 11 | devfs | 2 | fs | ❌ | 默认 | `[DKM:devfs]` | /dev/version, /dev/fb0 等 | ⬜ | |
|
||||
| 12 | e1000 | 3 | net | ❌ | `-device e1000` | `tx=ready rx=ready` | DHCP + ping | ⬜ | |
|
||||
| 13 | virtio_net | 3 | net | ❌ | `-device virtio-net-pci` | `[DKM:virtio_net] 1af4:1001 found` | capability 枚举 | ⬜ | |
|
||||
| 14 | ath9k | 3 | net | ❌ | (QEMU 不支持 WiFi) | `no Atheros WiFi device found` | 跳过(QEMU 限制) | ⏭ | |
|
||||
| 15 | ps2kbd | 3 | input | ❌ | 默认 | scan code 读取 | 输入回显 | ⬜ | |
|
||||
|
||||
## stage 加载顺序
|
||||
|
||||
```
|
||||
stage 0 (platform): timer → apic → acpi → pci
|
||||
stage 1 (boot): console_fb → ahci → nvme → bootfs
|
||||
stage 2 (fs): vfs → fat32 → devfs
|
||||
stage 3 (optional): e1000 → virtio_net → ath9k → ps2kbd
|
||||
```
|
||||
|
||||
## 测试设备 QEMU 参数
|
||||
|
||||
### AHCI + FAT32 测试盘
|
||||
|
||||
```
|
||||
-drive id=sata0,format=raw,file=.build_tmp/sata_fat32_dsk.img,if=none ^
|
||||
-device ide-hd,drive=sata0,bus=ide.0 ^
|
||||
```
|
||||
|
||||
### NVMe
|
||||
|
||||
```
|
||||
-device nvme,drive=nvme0,serial=UTSMTEST ^
|
||||
-drive id=nvme0,format=raw,file=.build_tmp/nvme_test.img,if=none ^
|
||||
```
|
||||
|
||||
### e1000
|
||||
|
||||
```
|
||||
-netdev user,id=net0 ^
|
||||
-device e1000,netdev=net0,mac=52:54:00:12:34:56 ^
|
||||
```
|
||||
|
||||
### virtio-net
|
||||
|
||||
```
|
||||
-netdev user,id=net0 ^
|
||||
-device virtio-net-pci,netdev=net0 ^
|
||||
```
|
||||
|
||||
## 已知限制
|
||||
|
||||
- NVMe BAR0 在 QEMU 中常位于 4G 以上,当前 HHDM 不能安全访问,需 Phase 0 高位 MMIO 映射解决
|
||||
- ath9k 在 QEMU 中无对应设备模拟,永远走 "not found" 路径
|
||||
- 多个 NIC 同时挂载会改变 PCI 拓扑,可能影响 e1000 探测位置
|
||||
@@ -0,0 +1,77 @@
|
||||
# Linux 兼容层测试矩阵
|
||||
|
||||
> 对应计划 Phase A:UTSM+Linux 双内核 park-and-resume 端到端验证
|
||||
> 前置条件:Linux 6.6 LTS bzImage 已构建(SYSTEM/boot/linux-bzImage + linux-initrd.img)
|
||||
|
||||
## 状态: ⬜ PENDING
|
||||
|
||||
## 测试环境
|
||||
|
||||
- QEMU 加速: WHPX (`-accel whpx -cpu max`),TCG 不支持 VMX
|
||||
- Linux 模块: limine.conf 中 bzImage/initrd 模块已启用
|
||||
- 串口: `-serial stdio`,过滤 `Linux version|utsm-linux|linux_compat|UTSM.*Linux|DSK|shell`
|
||||
|
||||
## 测试矩阵
|
||||
|
||||
| # | 测试项 | 串口/Shell 预期 | 状态 | 失败处理 | Bug# |
|
||||
|---|---|---|---|---|---|
|
||||
| A5.1 | UTSM VMM self-test 通过 | `[UTSM] VMM self-test PASS` | ⬜ | 检查 VMCS/EPT 初始化;BIOS 启用 VT-x | |
|
||||
| A5.2 | bzImage 加载与解析 | `[UTSM] Linux bzImage loaded` | ⬜ | 检查 linux_loader_init header magic 校验 | |
|
||||
| A5.3 | EPT 映射 + vmlaunch | `[UTSM] Linux guest launched` | ⬜ | 检查 EPT 表、VMCS guest 状态 | |
|
||||
| A5.4 | Linux 内核启动 | `Linux version 6.6.x` 串口日志 | ⬜ | 检查 cmdline、boot_params、E820 表 | |
|
||||
| A5.5 | init 脚本运行 | `[utsm-linux] init started` | ⬜ | 检查 initramfs 结构 | |
|
||||
| A5.6 | exec daemon 启动 + park | `[utsm-linux] starting utsm_exec_daemon...` → `linux_compat_init() ready` | ⬜ | 检查 daemon 编译、IPC 共享内存初始化 | |
|
||||
| A5.7 | DSK 正常接管 | `[DSK] boot` → `[DSK] SELFTEST PASS` | ⬜ | 验证 Linux park 不阻塞 DSK | |
|
||||
| A5.8 | shell `linux`(无参)状态查询 | `Linux 兼容层已就绪 (双内核 park-and-resume)` | ⬜ | 检查 reserved[5] 传递链 | |
|
||||
| A5.9 | shell `linux ls` | 输出 initramfs 根目录内容 | ⬜ | 检查 IPC exec 协议、vmresume 路径 | |
|
||||
| A5.10 | shell `linux uname -a` | 输出 `Linux ... 6.6.x ...` | ⬜ | 同上 | |
|
||||
| A5.11 | shell `linux cat /etc/hostname` | 输出 hostname | ⬜ | 同上 | |
|
||||
| A5.12 | 错误路径:`linux nosuchprog` | 输出 exec 失败,shell 不崩溃 | ⬜ | 检查 EXEC_EXIT 消息处理 | |
|
||||
|
||||
## 关键约束验证
|
||||
|
||||
| 约束 | 验证方法 | 状态 |
|
||||
|---|---|---|
|
||||
| Linux guest cmdline 含 `nohlt idle=poll` | 检查 [linux_loader.c](../../CODE/UTSM/vmm/linux_loader.c) cmdline 构造 | ⬜ |
|
||||
| IPC 共享内存 GPA=0x04000000, 1MB | e820 中标记 RESERVED,Linux 不分配 | ⬜ |
|
||||
| Linux guest RAM 起始 0x05000000 | 检查 EPT 映射范围 | ⬜ |
|
||||
| exec daemon 先发 EXEC_READY 再 HLT | daemon 源码 [utsm_exec_daemon.c](../../CODE/linux/initramfs/bin/utsm_exec_daemon.c) | ⬜ |
|
||||
| UTSM hypercall ABI: RAX=magic\|op | 检查 [hypercall.c](../../CODE/UTSM/vmm/hypercall.c) 处理 | ⬜ |
|
||||
|
||||
## 已知限制
|
||||
|
||||
- QEMU TCG 不支持 VMX,必须 WHPX 或真机
|
||||
- WHPX 可能不暴露 nested VMX 给 guest(需实测)
|
||||
- 若 CPU 不支持 VT-x,整个 Linux 兼容层降级为"不可用",不影响其他系统功能
|
||||
|
||||
## 手动测试命令
|
||||
|
||||
进入 shell 后执行:
|
||||
|
||||
```
|
||||
deshab:/ $ linux
|
||||
deshab:/ $ linux ls
|
||||
deshab:/ $ linux uname -a
|
||||
deshab:/ $ linux cat /etc/hostname
|
||||
deshab:/ $ linux nosuchprog
|
||||
```
|
||||
|
||||
## 串口日志锚点
|
||||
|
||||
启动后期望按顺序出现:
|
||||
|
||||
```
|
||||
[UTSM] VMM self-test PASS
|
||||
[UTSM] Linux bzImage loaded
|
||||
[UTSM] Linux guest launched
|
||||
Linux version 6.6.x ...
|
||||
[utsm-linux] init started
|
||||
[utsm-linux] kernel: 6.6.x
|
||||
[utsm-linux] starting utsm_exec_daemon...
|
||||
[utsm-linux] daemon PID=...
|
||||
[utsm-linux] init: daemon running, entering idle hold
|
||||
[UTSM] linux_compat service ready
|
||||
[DSK] boot
|
||||
[DSK] SELFTEST PASS
|
||||
... (进入 shell 提示符)
|
||||
```
|
||||
@@ -0,0 +1,62 @@
|
||||
# 网络端到端测试矩阵
|
||||
|
||||
> 对应计划 Phase C4 网络部分:e1000 + net_stack + ping/curl/browser
|
||||
|
||||
## 状态: ✅ 已验证([deshab_system_roadmap_plan.md](../../.trae/documents/deshab_system_roadmap_plan.md) Phase 1)
|
||||
|
||||
> 本矩阵用于回归验证,确保不退化
|
||||
|
||||
## 测试环境
|
||||
|
||||
- QEMU 网络: `-netdev user,id=net0 -device e1000,netdev=net0`
|
||||
- slirp 默认: guest 10.0.2.15, 网关 10.0.2.2, DNS 10.0.2.3
|
||||
- 主机 http 服务: `python -m http.server 8000`
|
||||
|
||||
## 测试矩阵
|
||||
|
||||
| # | 测试项 | 命令 | 预期 | 状态 | Bug# |
|
||||
|---|---|---|---|---|---|
|
||||
| N1 | e1000 驱动加载 | (自动) | `tx=ready rx=ready` | ✅ | |
|
||||
| N2 | netman 注册 | (自动) | netman 打印设备枚举 | ✅ | |
|
||||
| N3 | DHCP 获取 IP | (自动) | netman DHCP final rc=0 | ✅ | |
|
||||
| N4 | ARP 解析网关 | (自动) | netman ARP final rc=0 | ✅ | |
|
||||
| N5 | DNS 查询 | (自动) | netman DNS final rc=0 | ✅ | |
|
||||
| N6 | shell ping 网关 | `ping 10.0.2.2` | 4/4 reply, RTT<10ms | ✅ | |
|
||||
| N7 | shell ping 外网 | `ping 8.8.8.8` | (依赖主机联网) | 🔶 | |
|
||||
| N8 | shell curl 本地 | `curl http://10.0.2.2:8000/` | HTTP 200 + 目录 HTML | ✅ | |
|
||||
| N9 | shell curl 外网 | `curl http://example.com/` | HTTP 200 (依赖主机联网) | 🔶 | |
|
||||
| N10 | curl.elf 工具 | `run CURL.ELF` | 独立工具执行 curl | ✅ | |
|
||||
| N11 | ping.elf 工具 | `run PING.ELF` | 独立工具执行 ping | ✅ | |
|
||||
| N12 | browser.elf 工具 | `run BROWSER.ELF` | URL 输入 + HTTP GET | ✅ | |
|
||||
|
||||
## 回归验证
|
||||
|
||||
每次启动 dev_mode 时,run_dev_tests 应包含:
|
||||
|
||||
```
|
||||
[shell] dev_tests:
|
||||
...
|
||||
ping 10.0.2.2: OK (4/4 reply, RTT=Xms)
|
||||
...
|
||||
```
|
||||
|
||||
若 ping 失败:
|
||||
|
||||
1. 检查 e1000 是否加载(`-device e1000` 参数)
|
||||
2. 检查 netman 是否成功 DHCP
|
||||
3. 检查 ARP 是否解析网关
|
||||
4. 串口日志 grep `e1000|netman|DHCP|ARP|DNS|network`
|
||||
|
||||
## 性能基线
|
||||
|
||||
参见 [performance-baseline.md](performance-baseline.md):
|
||||
|
||||
- ping RTT < 10ms
|
||||
- curl 64KB 页面接收无明显停顿
|
||||
- DHCP 总耗时 < 5s
|
||||
|
||||
## 已知限制
|
||||
|
||||
- HTTPS/TLS 不支持(curl 仅 http)
|
||||
- TCP 仅最小 client 实现(无拥塞控制/乱序队列)
|
||||
- QEMU slirp 不支持真实 Wi-Fi 模式,ath9k 驱动在 QEMU 中无设备
|
||||
@@ -0,0 +1,72 @@
|
||||
# PE/EXE 兼容层测试矩阵
|
||||
|
||||
> 对应计划 Phase B:PE32+ (64位 native) 与 PE32 (32位 x86emu32) 兼容层验证
|
||||
> 入口:cmd.elf 通过 `ctx->reserved[4]` 取 pe_service
|
||||
|
||||
## 状态: ⬜ PENDING
|
||||
|
||||
## 测试程序
|
||||
|
||||
| 文件 | 类型 | 来源 | FAT32 8.3 名 | 路径 |
|
||||
|---|---|---|---|---|
|
||||
| hello64.exe | PE32+ (64位) | MinGW/MSVC 编译或 Python 生成 | `HELLO64 EXE` | SYSTEM/system/deshab64/tools/ |
|
||||
| hello32.exe | PE32 (32位) | MinGW 交叉编译或 Python 生成 | `HELLO32 EXE` | SYSTEM/system/deshab64/tools/ |
|
||||
|
||||
## 测试矩阵
|
||||
|
||||
| # | 测试项 | 命令 | 预期输出 | 状态 | Bug# |
|
||||
|---|---|---|---|---|---|
|
||||
| B2.1 | PE32+ 加载执行 | `pe HELLO64.EXE` | `Hello from PE32+!` | ⬜ | |
|
||||
| B2.2 | PE32 加载执行(解释器) | `pe HELLO32.EXE` | `Hello from PE32!` | ⬜ | |
|
||||
| B2.3 | PE 头解析 | `peinfo HELLO64.EXE` | `machine=0x8664 entry=0x... image_base=0x...` | ⬜ | |
|
||||
| B2.4 | 文件不存在错误路径 | `pe NONEXIST.EXE` | `Error: file not found` | ⬜ | |
|
||||
| B2.5 | 无参用法提示 | `pe` | 显示用法 | ⬜ | |
|
||||
| B2.6 | ExitProcess 返回 | (执行后) | cmd 接管,longjmp 跳回 pe_service_run | ⬜ | |
|
||||
| B2.7 | PE32 头解析 | `peinfo HELLO32.EXE` | `machine=0x14c entry=0x... image_base=0x00400000` | ⬜ | |
|
||||
|
||||
## 关键 ABI 验证
|
||||
|
||||
| ABI | 验证方法 | 状态 |
|
||||
|---|---|---|
|
||||
| `ctx->reserved[4]` 持 pe_service* | [cmd/main.c:825](../../CODE/cmd/main.c#L825) | ⬜ |
|
||||
| `PE_SERVICE_MAGIC` 校验 | [cmd/main.c:830](../../CODE/cmd/main.c#L830) | ⬜ |
|
||||
| `g_pe_svc` 缓存 | [cmd/main.c:108](../../CODE/cmd/main.c#L108) | ⬜ |
|
||||
| PE32+ IAT 填 ms_abi shim | [pe_loader.c](../../CODE/UTSM/pe/pe_loader.c) | ⬜ |
|
||||
| PE32 IAT 填合成地址 0x00010000\|idx | [pe_loader.c](../../CODE/UTSM/pe/pe_loader.c) | ⬜ |
|
||||
| x86emu32 拦截 CALL 合成地址 | [x86emu32.c](../../CODE/UTSM/pe/x86emu32.c) | ⬜ |
|
||||
|
||||
## 测试程序源码
|
||||
|
||||
### hello64.c (PE32+)
|
||||
|
||||
```c
|
||||
#include <windows.h>
|
||||
int main(void) {
|
||||
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "Hello from PE32+!\r\n", 19, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
编译:`x86_64-w64-mingw32-gcc -o hello64.exe hello64.c` 或 `cl /Fe:hello64.exe hello64.c`
|
||||
|
||||
### hello32.c (PE32)
|
||||
|
||||
```c
|
||||
#include <windows.h>
|
||||
int main(void) {
|
||||
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "Hello from PE32!\r\n", 18, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
编译:`i686-w64-mingw32-gcc -o hello32.exe hello32.c -Wl,--image-base=0x00400000`
|
||||
|
||||
### Fallback: Python 生成器
|
||||
|
||||
若无 MinGW/MSVC,使用 [CODE/tools/pe-samples/gen_pe.py](../../CODE/tools/pe-samples/gen_pe.py) 生成最小 PE 程序。
|
||||
|
||||
## 已知限制
|
||||
|
||||
- pe_shim 实现的 Win32 API 子集有限,测试程序仅使用 WriteFile + ExitProcess
|
||||
- x86emu32 指令覆盖率参见 [x86emu32-coverage.md](x86emu32-coverage.md)
|
||||
- TLS / IFUNC / lazy binding 不支持(DKM ABI 约束)
|
||||
@@ -0,0 +1,88 @@
|
||||
# 性能基线测量
|
||||
|
||||
> 对应计划 Phase C5:基于 TSC 的关键性能指标测量
|
||||
|
||||
## 状态: ⬜ PENDING
|
||||
|
||||
## 测量方法
|
||||
|
||||
所有指标基于 TSC(Time Stamp Counter):
|
||||
|
||||
```c
|
||||
static inline u64 rdtsc(void) {
|
||||
u32 lo, hi;
|
||||
__asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
|
||||
return ((u64)hi << 32) | lo;
|
||||
}
|
||||
```
|
||||
|
||||
TSC 频率需先校准(PIT 100ms busy-wait 测量):
|
||||
|
||||
```c
|
||||
u64 tsc_freq; // Hz
|
||||
u64 calibrate_tsc(void) {
|
||||
u64 start = rdtsc();
|
||||
pit_busy_wait(100); // 100ms
|
||||
u64 end = rdtsc();
|
||||
return (end - start) * 10; // ×10 得到 Hz
|
||||
}
|
||||
```
|
||||
|
||||
时间换算:`ms = (tsc_diff * 1000) / tsc_freq`
|
||||
|
||||
## 基线指标
|
||||
|
||||
| # | 指标 | 测量位置 | 基线目标 | 实测 | 状态 |
|
||||
|---|---|---|---|---|---|
|
||||
| P1 | UTSM 启动到 DSK SELFTEST | UTSM entry → DSK selftest pass | < 500ms (QEMU) | | ⬜ |
|
||||
| P2 | DSK 加载 shell.elf 时间 | FAT32 read + PIE load 包围 | < 200ms | | ⬜ |
|
||||
| P3 | DSK 加载 desktop.elf 时间 | 同上 | < 200ms | | ⬜ |
|
||||
| P4 | shell `ping 10.0.2.2` RTT | echo request → reply | < 10ms (user-net) | | ⬜ |
|
||||
| P5 | shell `linux ls` 完整 RTT | IPC exec round-trip | < 100ms (park-and-resume) | | ⬜ |
|
||||
| P6 | shell `run PING.ELF` 加载时间 | FAT32 read + PIE load | < 150ms | | ⬜ |
|
||||
| P7 | desktop 窗口拖动帧率 | 帧计数/TSC | 30+ FPS | | ⬜ |
|
||||
| P8 | `pe HELLO64.EXE` 加载+执行 | pe_service_run 包围 | < 50ms | | ⬜ |
|
||||
| P9 | `pe HELLO32.EXE` 加载+执行 | x86emu32 解释 | < 200ms | | ⬜ |
|
||||
| P10 | UTSM VMM self-test | vmm_init → vmm_self_test | < 50ms | | ⬜ |
|
||||
| P11 | Linux guest 启动到 park | vmlaunch → daemon HLT | < 3s (QEMU WHPX) | | ⬜ |
|
||||
| P12 | e1000 DHCP 完整耗时 | netman DHCP start → final rc | < 5s | | ⬜ |
|
||||
|
||||
## 自动化测量
|
||||
|
||||
在 dev_mode run_dev_tests 中追加性能测量代码:
|
||||
|
||||
```c
|
||||
/* 在 run_dev_tests 开头校准 TSC */
|
||||
u64 tsc_freq = calibrate_tsc();
|
||||
logl("[shell] TSC freq: <Hz>");
|
||||
|
||||
/* 各项测试包围 TSC */
|
||||
u64 t0 = rdtsc();
|
||||
/* ... 操作 ... */
|
||||
u64 t1 = rdtsc();
|
||||
u64 ms = (t1 - t0) * 1000 / tsc_freq;
|
||||
logl("[shell] perf: <name> = <ms>ms");
|
||||
```
|
||||
|
||||
输出到串口日志,由 [ISO/run_tests.bat](../../ISO/run_tests.bat) 收集汇总。
|
||||
|
||||
## 性能回归检测
|
||||
|
||||
```powershell
|
||||
# 比较两次测试结果
|
||||
$prev = Get-Content ISO/logs/perf-baseline-prev.json | ConvertFrom-Json
|
||||
$curr = Get-Content ISO/logs/perf-baseline-curr.json | ConvertFrom-Json
|
||||
|
||||
foreach ($m in $curr.metrics) {
|
||||
$p = $prev.metrics | Where-Object name -eq $m.name
|
||||
if ($p -and $m.ms -gt $p.ms * 1.5) {
|
||||
Write-Host "[REGRESSION] $($m.name): $($p.ms)ms -> $($m.ms)ms (>50%)"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 已知限制
|
||||
|
||||
- QEMU 性能数据不等于真机,仅作回归参考
|
||||
- WHPX vs TCG 性能差异巨大,必须固定加速方案
|
||||
- 多次测量取中位数,避免单次抖动
|
||||
@@ -0,0 +1,76 @@
|
||||
# 用户态程序功能矩阵
|
||||
|
||||
> 对应计划 Phase C4:FirstInit/login/desktop/shell/cmd + 5 个工具应用
|
||||
|
||||
## 状态: ⬜ PENDING
|
||||
|
||||
## 程序矩阵
|
||||
|
||||
| # | 程序 | ELF 路径 | 入口 | 关键命令/功能 | 验证点 | 状态 | Bug# |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 1 | FirstInit | `system/user/use/FirstInit.elf` | 首启触发 | 计算机名/用户名/密码输入、空字段红字、网络配置 | SHA256 密码、user.conf 写入缓冲 | ⬜ | |
|
||||
| 2 | login | `system/user/use/login.elf` | 次启触发 | 用户选择、密码输入、错误重试 | USER.CONF 解密、密码匹配 | ⬜ | |
|
||||
| 3 | desktop | `system/deshab64/desktop.elf` | login 后 | 双击图标、窗口拖动、任务栏、内建 bash | 6 个工具启动、鼠标光标 | ⬜ | |
|
||||
| 4 | shell | `system/deshab64/shell.elf` | desktop Terminal | ls/cat/cp/mv/rm/echo>/ping/curl/run/linux | dev_mode 自动测试全绿 | ⬜ | |
|
||||
| 5 | cmd | `system/deshab64/cmd.elf` | desktop CMD | dir/type/copy/del + `pe <NAME.EXE>` | PE 兼容层调用 | ⬜ | |
|
||||
| 6 | netman | `system/deshab64/network/netman.elf` | DSK 调度 | 读 conf.conf、应用网络配置 | DHCP/静态 IP | ⬜ | |
|
||||
| 7 | mouseInit | `system/deshab64/mouse/mouseInit.elf` | DSK 调度 | 安全 stub | 不阻塞启动 | ⬜ | |
|
||||
| 8 | editor | `system/deshab64/tools/editor.elf` | desktop 双击 | 文件打开/编辑/保存 | FAT32 写盘 | ⬜ | |
|
||||
| 9 | fileman | `system/deshab64/tools/fileman.elf` | desktop 双击 | 浏览/打开/复制 | 目录遍历 | ⬜ | |
|
||||
| 10 | browser | `system/deshab64/tools/browser.elf` | desktop 双击 | URL 输入/HTTP GET | net_stack 协议栈 | ⬜ | |
|
||||
| 11 | curl | `system/deshab64/tools/curl.elf` | desktop 双击 | `curl http://...` | HTTP GET | ⬜ | |
|
||||
| 12 | ping | `system/deshab64/tools/ping.elf` | desktop 双击 | `ping <ip>` | ICMP echo | ⬜ | |
|
||||
|
||||
## 启动链路
|
||||
|
||||
```
|
||||
首启: utsm → DSK → mouseInit → netman → FirstInit → desktop
|
||||
次启: utsm → DSK → login → desktop
|
||||
dev_mode: utsm → DSK → shell(dev_tests) → Esc → login → desktop
|
||||
desktop → 双击 Terminal → shell.elf
|
||||
desktop → 双击 CMD → cmd.elf
|
||||
shell → run FILEMAN.ELF → fileman.elf → Esc 返回 shell
|
||||
shell → run BROWSER.ELF → browser.elf
|
||||
shell → run EDITOR.ELF → editor.elf
|
||||
shell → run PING.ELF → ping.elf
|
||||
shell → run CURL.ELF → curl.elf
|
||||
```
|
||||
|
||||
## 详细测试用例
|
||||
|
||||
### shell 命令测试
|
||||
|
||||
| 命令 | 参数 | 预期 | 状态 |
|
||||
|---|---|---|---|
|
||||
| `ls` | (无) | 列出根目录文件(DESHAB.ELF, SHELL.ELF 等) | ⬜ |
|
||||
| `pwd` | (无) | `/` | ⬜ |
|
||||
| `cat` | `README.TXT` | 显示文件内容 | ⬜ |
|
||||
| `cp` | `a b` | 复制成功 | ⬜ |
|
||||
| `mv` | `a b` | 移动成功 | ⬜ |
|
||||
| `rm` | `a` | 删除成功 | ⬜ |
|
||||
| `echo>` | `text > file` | 写入文件 | ⬜ |
|
||||
| `ping` | `10.0.2.2` | 4/4 reply | ⬜ |
|
||||
| `curl` | `http://10.0.2.2:8000/` | HTTP 200 + body | ⬜ |
|
||||
| `run` | `PING.ELF` | 加载并执行 ping | ⬜ |
|
||||
| `linux` | (无) | 显示兼容层状态 | ⬜ |
|
||||
| `linux` | `ls` | 输出 initramfs 内容 | ⬜ |
|
||||
| `help` | (无) | 显示命令列表 | ⬜ |
|
||||
| `ver`/`version` | (无) | 显示版本 | ⬜ |
|
||||
|
||||
### desktop UI 测试
|
||||
|
||||
| 操作 | 预期 | 状态 |
|
||||
|---|---|---|
|
||||
| 双击 Terminal 图标 | 打开 shell 窗口 | ⬜ |
|
||||
| 双击 CMD 图标 | 打开 cmd 窗口 | ⬜ |
|
||||
| 双击 Editor 图标 | 打开 editor | ⬜ |
|
||||
| 双击 File Manager 图标 | 打开 fileman | ⬜ |
|
||||
| 双击 Browser 图标 | 打开 browser | ⬜ |
|
||||
| 鼠标移动 | 光标跟随,无闪烁 | ⬜ |
|
||||
| 窗口拖动 | 流畅,无撕裂 | ⬜ |
|
||||
| 任务栏点击 | 窗口切换 | ⬜ |
|
||||
|
||||
## 已知问题
|
||||
|
||||
- fileman.elf 之前触发过 QEMU 退出(访问未支持 boot context 字段),需观察是否复现
|
||||
- 真实 TTF 字体未运行时光栅化,使用预渲染位图(已知设计选择,非 bug)
|
||||
@@ -0,0 +1,86 @@
|
||||
# x86emu32 指令覆盖率测试
|
||||
|
||||
> 对应计划 Phase B3:枚举 x86emu32.c 已实现指令,验证覆盖率
|
||||
|
||||
## 状态: ⬜ PENDING
|
||||
|
||||
## 已实现指令清单
|
||||
|
||||
> 待根据 [x86emu32.c](../../CODE/UTSM/pe/x86emu32.c) 实际代码枚举填充
|
||||
|
||||
### 数据传送
|
||||
|
||||
| 指令 | 操作码 | 测试程序 | 预期 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| MOV r32, imm32 | B8+rd | `mov eax, 0x12345678` | eax=0x12345678 | ⬜ |
|
||||
| MOV r32, r/m32 | 8B /r | `mov eax, ebx` | eax=ebx | ⬜ |
|
||||
| MOV r/m32, r32 | 89 /r | `mov [esi], eax` | [esi]=eax | ⬜ |
|
||||
| PUSH r32 | 50+rd | `push eax` | [esp]=eax, esp-=4 | ⬜ |
|
||||
| POP r32 | 58+rd | `pop eax` | eax=[esp], esp+=4 | ⬜ |
|
||||
|
||||
### 算术运算
|
||||
|
||||
| 指令 | 操作码 | 测试程序 | 预期 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| ADD r32, r/m32 | 03 /r | `add eax, ebx` | eax=eax+ebx | ⬜ |
|
||||
| SUB r32, r/m32 | 2B /r | `sub eax, ebx` | eax=eax-ebx | ⬜ |
|
||||
| INC r32 | FF /0 | `inc eax` | eax=eax+1 | ⬜ |
|
||||
| DEC r32 | FF /1 | `dec eax` | eax=eax-1 | ⬜ |
|
||||
| MUL r/m32 | F7 /4 | `mul ebx` | edx:eax=eax*ebx | ⬜ |
|
||||
| DIV r/m32 | F7 /6 | `div ebx` | eax=edx:eax/ebx | ⬜ |
|
||||
|
||||
### 逻辑运算
|
||||
|
||||
| 指令 | 操作码 | 测试程序 | 预期 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| AND r32, r/m32 | 23 /r | `and eax, ebx` | eax=eax&ebx | ⬜ |
|
||||
| OR r32, r/m32 | 0B /r | `or eax, ebx` | eax=eax\|ebx | ⬜ |
|
||||
| XOR r32, r/m32 | 33 /r | `xor eax, ebx` | eax=eax^ebx | ⬜ |
|
||||
| NOT r/m32 | F7 /2 | `not eax` | eax=~eax | ⬜ |
|
||||
|
||||
### 控制流
|
||||
|
||||
| 指令 | 操作码 | 测试程序 | 预期 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| JMP rel32 | E9 cw/cd | `jmp label` | rip=label | ⬜ |
|
||||
| JMP r/m32 | FF /4 | `jmp eax` | rip=eax | ⬜ |
|
||||
| CALL rel32 | E8 cd | `call func` | push rip, rip=func | ⬜ |
|
||||
| RET | C3 | `ret` | pop rip | ⬜ |
|
||||
| Jcc rel32 | 0F 8x cd | `jz label` | 条件跳转 | ⬜ |
|
||||
|
||||
### 字符串操作
|
||||
|
||||
| 指令 | 操作码 | 测试程序 | 预期 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| MOVSB | A4 | `movsb` | [edi]=[esi], inc/dec | ⬜ |
|
||||
| STOSB | AA | `stosb` | [edi]=al, inc/dec | ⬜ |
|
||||
| REP MOVSB | F3 A4 | `rep movsb` | 重复 ecx 次 | ⬜ |
|
||||
| REP STOSB | F3 AA | `rep stosb` | 重复 ecx 次 | ⬜ |
|
||||
|
||||
### 堆栈与控制
|
||||
|
||||
| 指令 | 操作码 | 测试程序 | 预期 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| ENTER imm16, imm8 | C8 iw ib | `enter 8, 0` | 建立栈帧 | ⬜ |
|
||||
| LEAVE | C9 | `leave` | 释放栈帧 | ⬜ |
|
||||
| NOP | 90 | `nop` | 无操作 | ⬜ |
|
||||
| INT3 | CC | `int3` | 触发断点 | ⬜ |
|
||||
|
||||
## 测试 PE 程序
|
||||
|
||||
每个指令类别构造一个最小 PE32 测试程序,在 [CODE/tools/pe-samples/](../../CODE/tools/pe-samples/) 下:
|
||||
|
||||
- `test_arith.exe`:算术运算
|
||||
- `test_logic.exe`:逻辑运算
|
||||
- `test_control.exe`:控制流
|
||||
- `test_string.exe`:字符串操作
|
||||
|
||||
每个测试程序通过 WriteFile 输出结果到 cmd.elf,与预期对比。
|
||||
|
||||
## 覆盖率统计
|
||||
|
||||
```
|
||||
已测试指令数 / 已实现指令数 = 覆盖率
|
||||
```
|
||||
|
||||
目标:核心指令(MOV/ADD/SUB/CMP/JMP/CALL/RET/PUSH/POP)覆盖率 100%。
|
||||
@@ -0,0 +1,627 @@
|
||||
# Deshab 驱动模块 ABI 设计
|
||||
|
||||
本文记录 Deshab 内核启动驱动模块系统的 ABI、manifest、ELF loader、加载状态机和 stage0/stage1 boot module 方案。
|
||||
|
||||
---
|
||||
|
||||
## 1. 总体定义
|
||||
|
||||
驱动模块系统命名:
|
||||
|
||||
```text
|
||||
DKM = Deshab Kernel Module
|
||||
DSM = Driver Startup Manager
|
||||
```
|
||||
|
||||
当前规则:
|
||||
|
||||
```text
|
||||
驱动目录:SYSTEM/driver
|
||||
驱动清单:SYSTEM/driver/manifest.json
|
||||
驱动格式:ELF64 .drv
|
||||
加载模式:module loading
|
||||
启动顺序:staged loading
|
||||
内存模型:UTSM
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. driver_desc ABI
|
||||
|
||||
每个驱动必须导出三个符号:
|
||||
|
||||
```text
|
||||
driver_desc
|
||||
driver_init
|
||||
driver_exit
|
||||
```
|
||||
|
||||
### 2.1 driver_desc
|
||||
|
||||
```c
|
||||
#define DKM_DRIVER_MAGIC 0x444B4D31u /* "DKM1" */
|
||||
#define DKM_ABI_VERSION 1
|
||||
|
||||
struct dkm_driver_desc {
|
||||
uint32_t magic;
|
||||
uint16_t abi_version;
|
||||
uint16_t desc_size;
|
||||
|
||||
const char *name;
|
||||
const char *version;
|
||||
const char *vendor;
|
||||
|
||||
uint32_t driver_class;
|
||||
uint32_t stage;
|
||||
uint32_t flags;
|
||||
uint32_t priority;
|
||||
|
||||
const char *const *depends;
|
||||
uint32_t depends_count;
|
||||
|
||||
const char *const *provides;
|
||||
uint32_t provides_count;
|
||||
|
||||
uint64_t min_kernel_abi;
|
||||
uint64_t feature_bits;
|
||||
|
||||
uint64_t reserved0;
|
||||
uint64_t reserved1;
|
||||
};
|
||||
```
|
||||
|
||||
### 2.2 driver_class
|
||||
|
||||
```text
|
||||
DKM_CLASS_PLATFORM
|
||||
DKM_CLASS_BUS
|
||||
DKM_CLASS_INTERRUPT
|
||||
DKM_CLASS_TIMER
|
||||
DKM_CLASS_CONSOLE
|
||||
DKM_CLASS_STORAGE
|
||||
DKM_CLASS_FS
|
||||
DKM_CLASS_NET
|
||||
DKM_CLASS_INPUT
|
||||
DKM_CLASS_GPU
|
||||
DKM_CLASS_MISC
|
||||
```
|
||||
|
||||
### 2.3 flags
|
||||
|
||||
```text
|
||||
DKM_F_REQUIRED
|
||||
当前 stage 中失败则进入 DRR recovery 或 panic。
|
||||
|
||||
DKM_F_BOOT_MODULE
|
||||
可由 bootloader 预加载。
|
||||
|
||||
DKM_F_NO_UNLOAD
|
||||
不允许卸载。
|
||||
|
||||
DKM_F_STRONG_RECOVERY
|
||||
驱动 data 段使用 UTSM 强恢复策略。
|
||||
|
||||
DKM_F_DMA_REQUIRED
|
||||
驱动需要 DMA API。
|
||||
|
||||
DKM_F_EARLY_LOG
|
||||
驱动 init 期间允许使用 early log。
|
||||
```
|
||||
|
||||
### 2.4 driver_init / driver_exit
|
||||
|
||||
```c
|
||||
typedef int (*dkm_driver_init_fn)(const struct dkm_kernel_api *api,
|
||||
struct dkm_driver_handle *handle);
|
||||
|
||||
typedef int (*dkm_driver_exit_fn)(struct dkm_driver_handle *handle);
|
||||
```
|
||||
|
||||
约定:
|
||||
|
||||
```text
|
||||
driver_init 返回 0 表示成功。
|
||||
driver_init 返回负数表示失败。
|
||||
driver_exit 只用于非 NO_UNLOAD 驱动。
|
||||
required 驱动 init 失败会触发 DRR recovery 或 panic。
|
||||
optional 驱动 init 失败会被标记为 FAILED。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. kernel_api ABI
|
||||
|
||||
驱动不直接依赖任意内核符号,默认通过 `dkm_kernel_api` 调用内核服务。
|
||||
|
||||
### 3.1 API 总结构
|
||||
|
||||
```c
|
||||
#define DKM_KERNEL_API_VERSION 1
|
||||
|
||||
struct dkm_kernel_api {
|
||||
uint32_t version;
|
||||
uint32_t size;
|
||||
uint64_t feature_bits;
|
||||
|
||||
const struct dkm_log_api *log;
|
||||
const struct dkm_mem_api *mem;
|
||||
const struct dkm_utsm_api *utsm;
|
||||
const struct dkm_irq_api *irq;
|
||||
const struct dkm_pci_api *pci;
|
||||
const struct dkm_dma_api *dma;
|
||||
const struct dkm_vfs_api *vfs;
|
||||
const struct dkm_net_api *net;
|
||||
const struct dkm_timer_api *timer;
|
||||
const struct dkm_drr_api *drr;
|
||||
};
|
||||
```
|
||||
|
||||
### 3.2 log API
|
||||
|
||||
```c
|
||||
struct dkm_log_api {
|
||||
void (*info)(const char *fmt, ...);
|
||||
void (*warn)(const char *fmt, ...);
|
||||
void (*error)(const char *fmt, ...);
|
||||
void (*panic)(const char *fmt, ...);
|
||||
};
|
||||
```
|
||||
|
||||
### 3.3 memory API
|
||||
|
||||
```c
|
||||
struct dkm_mem_api {
|
||||
void *(*alloc)(uint64_t size, uint32_t flags);
|
||||
void (*free)(void *ptr);
|
||||
|
||||
void *(*alloc_pages)(uint32_t order, uint32_t flags);
|
||||
void (*free_pages)(void *ptr, uint32_t order);
|
||||
|
||||
void *(*mmio_map)(uint64_t phys, uint64_t size, uint32_t flags);
|
||||
void (*mmio_unmap)(void *virt, uint64_t size);
|
||||
};
|
||||
```
|
||||
|
||||
### 3.4 UTSM API
|
||||
|
||||
```c
|
||||
struct dkm_utsm_api {
|
||||
int (*create_segment)(uint64_t size, uint32_t flags, struct utsm_capability *out);
|
||||
int (*read)(struct utsm_capability cap, uint64_t off, void *dst, uint64_t len);
|
||||
int (*write)(struct utsm_capability cap, uint64_t off, const void *src, uint64_t len);
|
||||
int (*pin)(struct utsm_capability cap, uint64_t off, uint64_t len, void **window);
|
||||
int (*unpin)(void *window, uint32_t flags);
|
||||
};
|
||||
```
|
||||
|
||||
### 3.5 IRQ API
|
||||
|
||||
```c
|
||||
struct dkm_irq_api {
|
||||
int (*register_irq)(uint32_t vector, int (*handler)(void *ctx), void *ctx, uint32_t flags);
|
||||
int (*unregister_irq)(uint32_t vector);
|
||||
void (*ack)(uint32_t vector);
|
||||
};
|
||||
```
|
||||
|
||||
### 3.6 PCI API
|
||||
|
||||
```c
|
||||
struct dkm_pci_api {
|
||||
int (*scan)(int (*cb)(const struct pci_device *dev, void *ctx), void *ctx);
|
||||
int (*enable_device)(const struct pci_device *dev);
|
||||
uint64_t (*bar_phys)(const struct pci_device *dev, uint32_t bar);
|
||||
uint64_t (*bar_size)(const struct pci_device *dev, uint32_t bar);
|
||||
};
|
||||
```
|
||||
|
||||
### 3.7 DMA API
|
||||
|
||||
```c
|
||||
struct dkm_dma_api {
|
||||
int (*alloc)(uint64_t size, uint32_t flags, struct dkm_dma_buffer *out);
|
||||
void (*free)(struct dkm_dma_buffer *buf);
|
||||
int (*sync_for_device)(struct dkm_dma_buffer *buf);
|
||||
int (*sync_for_cpu)(struct dkm_dma_buffer *buf);
|
||||
};
|
||||
```
|
||||
|
||||
### 3.8 VFS / NET / TIMER / DRR API
|
||||
|
||||
第一版只定义边界:
|
||||
|
||||
```text
|
||||
vfs: register_fs / mount / open / read / write / close
|
||||
net: register_netdev / submit_tx / poll_rx
|
||||
timer: sleep_ns / call_later / monotonic_ns
|
||||
drr: register_recovery_ops / report_fault / mark_critical
|
||||
```
|
||||
|
||||
详细结构后续随对应子系统实现细化。
|
||||
|
||||
---
|
||||
|
||||
## 4. ELF Loader 支持的 relocation
|
||||
|
||||
第一版仅支持 x86_64 ELF64 小型内核模型。
|
||||
|
||||
### 4.1 必须支持
|
||||
|
||||
```text
|
||||
R_X86_64_64
|
||||
绝对 64-bit 地址重定位。
|
||||
|
||||
R_X86_64_RELATIVE
|
||||
base + addend。
|
||||
|
||||
R_X86_64_GLOB_DAT
|
||||
GOT 符号地址。
|
||||
|
||||
R_X86_64_JUMP_SLOT
|
||||
PLT 函数地址。
|
||||
```
|
||||
|
||||
### 4.2 建议支持
|
||||
|
||||
```text
|
||||
R_X86_64_PC32
|
||||
32-bit PC-relative 调用。
|
||||
|
||||
R_X86_64_PLT32
|
||||
PLT-relative 调用。
|
||||
|
||||
R_X86_64_32 / R_X86_64_32S
|
||||
仅允许确认地址范围安全时使用。
|
||||
```
|
||||
|
||||
### 4.3 第一版禁止
|
||||
|
||||
```text
|
||||
TLS relocation
|
||||
IFUNC
|
||||
lazy binding
|
||||
外部动态库依赖
|
||||
用户态 libc 依赖
|
||||
异常展开表强依赖
|
||||
```
|
||||
|
||||
### 4.4 加载流程
|
||||
|
||||
```text
|
||||
DKM_ELF_LOAD(path_or_boot_module)
|
||||
1. 读取 ELF header。
|
||||
2. 校验 ELFCLASS64 / EM_X86_64 / endian / ABI。
|
||||
3. 读取 program headers 或 section headers。
|
||||
4. 计算模块内存大小和对齐。
|
||||
5. 通过 UTSM 创建 code/data 段。
|
||||
6. 加载 PT_LOAD 或 SHF_ALLOC section。
|
||||
7. 清零 .bss。
|
||||
8. 解析 symbol table。
|
||||
9. 解析 relocation section。
|
||||
10. 将内核导出符号或 kernel_api 符号填入。
|
||||
11. 执行 relocation。
|
||||
12. 查找 driver_desc / driver_init / driver_exit。
|
||||
13. 设置 code 段 READ|EXEC|SEALED。
|
||||
14. 设置 data 段 READ|WRITE|STRONG_RECOVERY。
|
||||
15. 返回 module handle。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. manifest.json 格式
|
||||
|
||||
当前使用 JSON,不再使用 ini 格式的 manifest.drv。
|
||||
|
||||
路径:
|
||||
|
||||
```text
|
||||
SYSTEM/driver/manifest.json
|
||||
```
|
||||
|
||||
### 5.1 顶层字段
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": "deshab.driver.manifest.v1",
|
||||
"root": "SYSTEM",
|
||||
"driverRoot": "SYSTEM/driver",
|
||||
"format": "elf64-drv",
|
||||
"abi": {},
|
||||
"policy": {},
|
||||
"stages": []
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 abi 字段
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "DKM",
|
||||
"version": 1,
|
||||
"entry": "driver_init",
|
||||
"exit": "driver_exit",
|
||||
"descriptor": "driver_desc"
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 policy 字段
|
||||
|
||||
```json
|
||||
{
|
||||
"loadModel": "module",
|
||||
"loadOrder": "staged",
|
||||
"requiredFailure": "drr_recovery_or_panic",
|
||||
"optionalFailure": "mark_failed_and_continue",
|
||||
"memoryModel": "UTSM",
|
||||
"codeSegment": "READ|EXEC|SEALED",
|
||||
"dataSegment": "READ|WRITE|STRONG_RECOVERY",
|
||||
"dmaSegment": "DMA|PINNED"
|
||||
}
|
||||
```
|
||||
|
||||
### 5.4 stage 字段
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 0,
|
||||
"name": "platform",
|
||||
"required": true,
|
||||
"description": "平台发现、中断、总线、基础计时。",
|
||||
"drivers": []
|
||||
}
|
||||
```
|
||||
|
||||
### 5.5 driver 字段
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "pci",
|
||||
"path": "driver/bus/pci.drv",
|
||||
"class": "bus",
|
||||
"required": true,
|
||||
"depends": ["irq"],
|
||||
"provides": ["pci"]
|
||||
}
|
||||
```
|
||||
|
||||
### 5.6 路径规则
|
||||
|
||||
```text
|
||||
manifest 中的 path 相对 SYSTEM 根目录。
|
||||
SYSTEM/driver/manifest.json 内的 driver/bus/pci.drv 指向 SYSTEM/driver/bus/pci.drv。
|
||||
stage0/stage1 驱动允许来自 boot module,不要求文件系统已挂载。
|
||||
stage2/stage3 驱动默认从 SYSTEM/driver 加载。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 驱动加载状态机
|
||||
|
||||
```text
|
||||
DISCOVERED
|
||||
-> QUEUED
|
||||
-> DEP_WAIT
|
||||
-> LOADING
|
||||
-> ELF_CHECKED
|
||||
-> MEMORY_ALLOCATED
|
||||
-> RELOCATED
|
||||
-> ABI_CHECKED
|
||||
-> INITING
|
||||
-> ACTIVE
|
||||
```
|
||||
|
||||
失败状态:
|
||||
|
||||
```text
|
||||
FAILED_ELF
|
||||
FAILED_RELOCATION
|
||||
FAILED_DEPENDENCY
|
||||
FAILED_ABI
|
||||
FAILED_INIT
|
||||
FAILED_REQUIRED
|
||||
```
|
||||
|
||||
卸载状态:
|
||||
|
||||
```text
|
||||
ACTIVE
|
||||
-> QUIESCING
|
||||
-> EXITING
|
||||
-> UNLOADING
|
||||
-> UNLOADED
|
||||
```
|
||||
|
||||
恢复状态:
|
||||
|
||||
```text
|
||||
ACTIVE
|
||||
-> SUSPENDED_BY_DRR
|
||||
-> RECOVERING
|
||||
-> REINITING
|
||||
-> ACTIVE
|
||||
```
|
||||
|
||||
### 6.1 加载策略
|
||||
|
||||
```text
|
||||
1. DSM 读取 manifest.json。
|
||||
2. 按 stage 顺序加载。
|
||||
3. 每个 stage 内按 priority 排序。
|
||||
4. 检查 depends 是否已由 provides 满足。
|
||||
5. 未满足依赖的驱动进入 DEP_WAIT。
|
||||
6. 每轮加载成功后更新 provides set。
|
||||
7. 一轮后仍 DEP_WAIT 的 required 驱动进入 FAILED_REQUIRED。
|
||||
8. optional 驱动失败只记录状态。
|
||||
```
|
||||
|
||||
### 6.2 required 失败策略
|
||||
|
||||
```text
|
||||
stage0/stage1 required 失败:
|
||||
-> DRR report_fault
|
||||
-> 尝试 boot fallback
|
||||
-> 不可恢复则 panic / system rollback
|
||||
|
||||
stage2 required 失败:
|
||||
-> DRR recovery
|
||||
-> fallback 到 bootfs 或只读模式
|
||||
|
||||
stage3 optional 失败:
|
||||
-> mark FAILED
|
||||
-> continue boot
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. stage0/stage1 boot module 方案
|
||||
|
||||
问题:
|
||||
|
||||
```text
|
||||
stage0/stage1 负责 timer、irq、pci、bootfs、block 等早期能力。
|
||||
此时 VFS 和普通文件系统可能还没准备好。
|
||||
所以不能完全依赖 SYSTEM/driver 的普通文件遍历。
|
||||
```
|
||||
|
||||
### 7.1 Bootloader 预加载
|
||||
|
||||
bootloader 负责把关键文件作为 boot module 交给内核:
|
||||
|
||||
```text
|
||||
SYSTEM/driver/manifest.json
|
||||
SYSTEM/driver/platform/timer.drv
|
||||
SYSTEM/driver/platform/apic.drv
|
||||
SYSTEM/driver/bus/pci.drv
|
||||
SYSTEM/driver/fs/bootfs.drv
|
||||
```
|
||||
|
||||
可选:
|
||||
|
||||
```text
|
||||
SYSTEM/driver/console/console_fb.drv
|
||||
SYSTEM/driver/block/ahci.drv
|
||||
SYSTEM/driver/block/nvme.drv
|
||||
```
|
||||
|
||||
### 7.2 Boot Module 表
|
||||
|
||||
内核早期接收 boot module 表:
|
||||
|
||||
```c
|
||||
struct dkm_boot_module {
|
||||
const char *path;
|
||||
void *base;
|
||||
uint64_t size;
|
||||
uint32_t type;
|
||||
uint32_t flags;
|
||||
uint64_t checksum;
|
||||
};
|
||||
|
||||
struct dkm_boot_module_table {
|
||||
uint32_t count;
|
||||
struct dkm_boot_module modules[];
|
||||
};
|
||||
```
|
||||
|
||||
### 7.3 查找规则
|
||||
|
||||
```text
|
||||
DSM_LOAD_DRIVER(path)
|
||||
1. 如果 path 在 boot module table 中,直接从内存加载。
|
||||
2. 否则如果 VFS 已可用,从 SYSTEM/path 加载。
|
||||
3. 否则返回 BOOT_MODULE_NOT_FOUND。
|
||||
```
|
||||
|
||||
### 7.4 stage0/stage1 限制
|
||||
|
||||
```text
|
||||
1. 不依赖普通 VFS。
|
||||
2. 不依赖普通 heap。
|
||||
3. 优先使用 early allocator 或 DRR emergency-safe allocator。
|
||||
4. 日志使用 early log。
|
||||
5. 不启动复杂后台任务。
|
||||
6. 只注册最小服务能力。
|
||||
```
|
||||
|
||||
### 7.5 stage 切换点
|
||||
|
||||
```text
|
||||
stage0 完成:
|
||||
timer / irq / pci 基础能力可用。
|
||||
|
||||
stage1 完成:
|
||||
bootfs 或 block + fs 基础能力可用。
|
||||
|
||||
stage2 开始:
|
||||
VFS 可用,可以从 SYSTEM/driver 正常读取更多驱动。
|
||||
|
||||
stage3 开始:
|
||||
普通调度、网络、输入、图形等可异步加载。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 与 UTSM / DRR 的关系
|
||||
|
||||
### 8.1 UTSM 内存策略
|
||||
|
||||
```text
|
||||
驱动 text:READ | EXEC | SEALED
|
||||
驱动 rodata:READ | SEALED
|
||||
驱动 data:READ | WRITE | STRONG_RECOVERY
|
||||
驱动 bss:READ | WRITE | STRONG_RECOVERY
|
||||
驱动 DMA:DMA | PINNED,必要时 CIPHERTEXT_DMA 或 NO_ENCRYPT
|
||||
```
|
||||
|
||||
### 8.2 DRR 记录项
|
||||
|
||||
DRR 为每个驱动记录:
|
||||
|
||||
```text
|
||||
driver name
|
||||
stage
|
||||
state
|
||||
module memory range
|
||||
provided services
|
||||
recovery ops
|
||||
init result
|
||||
last fault
|
||||
```
|
||||
|
||||
### 8.3 驱动 recovery ops
|
||||
|
||||
驱动可注册:
|
||||
|
||||
```c
|
||||
struct dkm_driver_recovery_ops {
|
||||
int (*quiesce)(void *ctx);
|
||||
int (*reset)(void *ctx);
|
||||
int (*reinit)(void *ctx);
|
||||
int (*dump_state)(void *ctx, void *buf, uint64_t len);
|
||||
};
|
||||
```
|
||||
|
||||
DRR recovery 顺序:
|
||||
|
||||
```text
|
||||
quiesce -> UTSM rollback -> device reset -> driver reinit -> resume
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 第一版定稿
|
||||
|
||||
第一版驱动系统确定:
|
||||
|
||||
```text
|
||||
1. SYSTEM 是 IMG 内系统根目录。
|
||||
2. 驱动清单为 SYSTEM/driver/manifest.json。
|
||||
3. 驱动文件为 ELF64 .drv。
|
||||
4. 驱动必须导出 driver_desc / driver_init / driver_exit。
|
||||
5. 驱动通过 dkm_kernel_api 调用内核服务。
|
||||
6. ELF loader 第一版支持常用 x86_64 relocation。
|
||||
7. 驱动按 stage 分阶段加载。
|
||||
8. stage0/stage1 支持 bootloader 预加载 boot module。
|
||||
9. stage2/stage3 从 SYSTEM/driver 加载。
|
||||
10. 驱动内存纳入 UTSM,驱动恢复纳入 DRR。
|
||||
```
|
||||
Reference in New Issue
Block a user