feat(panic): FUCK [panic] mode=strict|fallback + realtest image variant

- UTSM panic_full returns in fallback mode (logs [PANIC:FALLBACK] + code + hit
  count); panic_halt keeps always-halt sites (CPU exception, VMM-E11 LA57,
  VMM-E15 DSK jump, UTSM-E42 test hook). Call sites given safe continuations.
- Mode passed to DSK/FirstInit/login/desktop via DSK_BOOT_FLAG_PANIC_FALLBACK;
  DKM kernel_api.panic / kern.log.panic return to driver; ext4 fatal aborts the
  op via setjmp/longjmp and DSK falls back to FAT32 ESP.
- build.ps1/Makefile: dev=strict, release=fallback, new realtest (release
  options + strict); default -Variant all; serialized iso packing under -j.
- Fix '*/' inside comments (dkm.h, kernel_api.h, bus.c) that broke the build.
- Includes pending work: dkm_bus service bus, mt7920/wlan drivers, desktop
  files/startmenu/prank, pe-tools, diskinfo, docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Linehu
2026-10-12 23:57:19 +08:00
co-authored by Cursor
parent a7e5b2bc7a
commit 8554a82677
84 changed files with 7325 additions and 484 deletions
@@ -0,0 +1,281 @@
# 万物互联与服务总线设计(DKM-BUS)
> 系列代号:**万物互联(Deshab Interconnect)**
> 路线:P0-P6,六阶段全量改造
> 状态源:[STATUS.md](../STATUS.md);任务板:[TASKBOARD.md](../TASKBOARD.md)(D6/D7 条目)
> 设计定稿:2026-10-10
---
## 0. 一句话
**没有主内核。utsm.elf 只剩"机制"(中断/内存/调度/恢复/封缄/panic/加载器),其余一切——驱动、文件系统、向导、登录、桌面、shell——都是平等的 DKM 内核模块,彼此只通过按名服务总线(kern.\* / srv.\*)互联。**
这是 library OS / 万物互联形态:程序即内核,模块间没有 syscall 边界,没有第二次内核交接。性能不是本设计的目标——按名查找、间接调用、注册-消费模式到处用,是刻意的(自由 > 快)。
```text
Limine → utsm.elf(唯一内核:IDT/IRQ、DMA、分页、arena、UTSM/UTRW、DRR、
PCQ 调度器、panic 莲花屏、DKM loader、服务总线宿主)
│ manifest.json 4+1 stage,全部 .drv(ET_REL),加载后常驻、永不被覆盖
stage0 platform: timer apic acpi pci
stage1 boot: console_fb ahci nvme ehci xhci bootfs
stage2 fs: vfs fat32(实装 R/W) ext4(新) devfs
stage3 optional: e1000 virtio_net ath9k wlan ps2kbd
stage4 session: ps2mouse session(协调器) netman firstinit login shell desktop cmd
↑ driver_init=注册服务;运行= srv.*.run 被调用 / 调度任务
│ 模块间唯一通信方式:服务总线(kern.* / srv.* 按名注册-消费)
终态:PCQ 调度器常驻(bootstrap 变 idle),desktop 等长期模块为任务,
输入走真 IRQ(IRQ1/12),无 DSK、无第二次内核交接、无 IF=0 时代
```
### 0.1 与 RTOS / 微内核的区别(定界)
- 这**不是** RTOS:不承诺调度延迟上界(O(1) 调度器结构上接近,但那是副产品)。
- 这也**不是**微内核:模块不在用户态,没有 IPC 权限检查,一切 Ring0——SAS-R0 约束不变。
- 最近亲缘:exokernel/library OS(程序即内核)+ multikernel 的"OS 即分布式系统"世界观(去中心服务表)。
---
## 1. 服务总线(dkm_bus)
### 1.1 从 kapi 到 bus
现有 `dkm_kapi_table`(`CODE/UTSM/dkm/kernel_api.c:95-136`)是静态只读表:只有内核能导出(14 项),驱动不能注册。总线把它双向化:
- **kern.\***:仅 UTSM 注册(内核本体 + 内核托管注册表的前端)。
- **srv.\***:任何 .drv 模块在 driver_init 里注册,任何模块消费。
- 旧 14 条无前缀 kapi 名(`log.info` 等)冻结不动(兼容层);总线播种时同时注册带 `kern.` 前缀的新名。终态(P6 收尾)kapi 静态表退役,总线成为唯一注册源。
### 1.2 数据结构与 API
新增 `CODE/UTSM/dkm/bus.c`;`include/utsm/dkm.h` **尾部追加**(不改任何既有字段,`kernel_api+0xA8` block 槽偏移不受影响):
```c
#define DKM_BUS_MAGIC 0x53425553u /* "SBUS" */
#define DKM_BUS_VERSION 1u
#define DKM_BUS_MAX_SERVICES 128
#define DKM_BUS_MAX_NAME 48
#define DKM_BUS_F_KERNEL 1u /* 内核注册,不可注销 */
#define DKM_BUS_F_NO_UNLOAD 2u /* 模块声明:注销即非法 */
typedef struct dkm_bus_service {
char name[DKM_BUS_MAX_NAME]; /* NUL 终止,必须带命名空间前缀 */
u32 version; /* 服务契约版本,消费方校验 */
u32 flags;
void *fn; /* 服务入口,签名由各服务契约定义 */
const struct dkm_driver_handle *provider; /* NULL = 内核 */
} dkm_bus_service;
typedef struct dkm_bus_api {
u32 magic, version;
int (*register_service)(const char *name, u32 version, void *fn);
int (*unregister_service)(const char *name);
int (*lookup)(const char *name, void **out_fn, u32 *out_version);
int (*probe)(const char *name, void **out_fn, u32 *out_version);
u32 (*count)(void);
const dkm_bus_service *(*at)(u32 index);
} dkm_bus_api;
/* dkm_kernel_api 尾部追加(kapi 之后):const dkm_bus_api *bus; */
/* 内核直连(kernel 不经函数指针调自己):
* const dkm_bus_api *dkm_bus_get_api(void);
* void dkm_bus_set_current_provider(struct dkm_driver_handle *h);
* loader 在 driver_init 前后设/清 current provider 上下文
* (仿 D4 dkm_log_set_driver 的位置与模式)。 */
```
### 1.3 失败策略(铁律映射)
| 操作 | miss / 违规时 | 语义 |
|---|---|---|
| `register_service` 名字非法(无命名空间前缀 / 非 srv.\* 却是模块) | `BUS-E01` panic | 编程错误 |
| `register_service` 重名 | `BUS-E02` panic | 编程错误 |
| `register_service` 表满 | `BUS-E03` panic | 容量规划错误 |
| `lookup` 未命中 | `BUS-E04 <名字>` panic | **硬依赖未满足 = 编程错误,绝不返回 NULL 伪装成功** |
| `probe` 未命中 | 返回 -1 | **能力缺席 = 设计内双路径**,调用方必须显式处理缺席,且该回退须登记 CLAUDE.md 白名单 |
| `unregister` 非 provider 本人 / F_NO_UNLOAD | panic | 生命周期违规 |
两级语义正好映射插桩铁律:该响的地方响(lookup),该静的地方显式静(probe + 白名单)。
### 1.4 命名空间
| 前缀 | 谁能注册 | 已规划服务 |
|---|---|---|
| `kern.*` | 仅 UTSM | `kern.log.info/warn/error/panic`、`kern.dma.alloc_pages`、`kern.irq.register`、`kern.irq.vector_alloc/free`、`kern.irq.unmask/mask`、`kern.mm.map_mmio/unmap_mmio`、`kern.apic.register_eoi`、`kern.drr.snapshot_dirty/rollback_pages`、`kern.utrw.debug_dump`、`kern.block.read/write`、`kern.config.get`、`kern.pe.service`、`kern.lxc.service`、`kern.probe.info`、`kern.dkm.load_by_name`、`kern.bootlog.milestone` |
| `srv.*` | 任何 .drv | `srv.input.mouse.poll`、`srv.input.kbd.poll`、`srv.fs.fat32.read_path/write_file/bootlog`、`srv.fs.ext4.*`、`srv.net.lease`、`srv.user.config`、`srv.auth.result`、`srv.session.dev_mode`、`srv.firstinit.run`、`srv.login.run`、`srv.desktop.run`、`srv.netman.run`、`srv.shell.run` |
规则:模块注册不带命名空间前缀或带 `kern.` → `BUS-E01`。名字长度 ≥ DKM_BUS_MAX_NAME → `BUS-E01`。
### 1.5 与 manifest depends/provides 的两层机制
manifest 的 depends/provides 今天是纯元数据(`dsm_load_stage_range` 只按数组顺序加载,不做校验)。总线设计引入两层强制:
**第一层:加载时序保证(P0)**
- DSM loader 维护 capability 集合(已加载驱动的 provides token 并集)。
- 每个驱动加载前校验其 depends 全部满足,miss → `DKM-E44 DEPENDENCY NOT SATISFIED` panic。
- 同 stage 内按依赖**不动点迭代**排序(多趟扫描直到无进展;环/死锁 → panic)。性能无所谓,正确性第一。
- driver_init 返回 0 后,登记该驱动 desc->provides 的 token。
**第二层:服务可发现性校验(P1)**
- loader 在 driver_init 成功返回后校验:**stage≥4 模块的每个 provides token `T` 必须对应至少一个已注册的 `srv.T` 或 `srv.T.*` 服务**,否则 `DKM-E45 PROVIDES NOT REGISTERED` panic。
- stage0-3 老 14 驱动豁免:它们的 provides 由内核侧注册表兑现(如 ahci → block registry),不经总线。豁免清单 = manifest.json 现有 stage0-3 全部条目,写死在 `dsm_verify_provides` 的注释里。
为什么 provides 不自动注册:loader 拿不到服务 fn 指针(注册哪些函数、什么签名是模块的自由)。所以是"模块主动注册 + loader 事后校验契约"——自由也要有地图,但地图由填图人自己画,loader 只查漏。
### 1.6 生命周期模型("程序变内核任务")
```text
load(ET_REL 重定位,kmem_alloc 永久内存——镜像覆盖问题就此灭绝)
→ driver_init(handle, api):只做 注册服务 + (长期模块)api->sched->task_create
(快、非交互;此时抢占未启用,满足 task_create 前置条件)
→ 控制权回到 DSM loader → stage4 全部完成 → 回 kernel_main
→ 排序者(P4 期间=残留 DSK,P5 起=session.drv)bus 调 srv.*.run 依次拉起
(一次性模块 call-and-return;交互式模块 run 内阻塞交互——与今天 DSK 阻塞在
login 上的行为一致,无回归)
→ P6 终态:utsm_sched_enable 常驻 + bootstrap park 成 idle;desktop 的 run 即
它创建的任务入口,由 PCQ 驱动;输入 IRQ 解屏蔽(IRQ1/12)
```
关键设计:**"运行"也是总线服务**(`srv.<mod>.run`)。这回答了"desktop 什么时候 driver_init"——在 UTSM 阶段、任何 UI 出现之前;init 只注册不运行;运行由排序者按总线调用发起。
loader 单线程不变式:session.drv 的 `kern.dkm.load_by_name` 在 stage 循环外被调(顺序执行 + loaded 标志防重入),总线无锁。任何未来并发加载都是契约违规。
---
## 2. 跨模块状态迁移表
现状真正跨模块耦合只有 `dsk_boot_context`(desktop.h 的 extern 全局是 desktop 单模块内多 TU 链接,`ld -r` 后原样工作)。逐槽消灭:
| 现状耦合通道 | 总线化后 | 提供方 |
|---|---|---|
| desktop `*(u64*)(api+0xA8)` 裸偏移读 block | `api->block` 字段直读(driver_init 拿到真 api 指针) | UTSM |
| `reserved[4]` pe_service | `kern.pe.service` | UTSM pe.c |
| `reserved[5]` lxc service | `kern.lxc.service` | UTSM linux_compat.c |
| `reserved[6]` probe_info | `kern.probe.info` | UTSM probe.c |
| `reserved[7]` net_lease | `srv.net.lease`(fn 返回 const net_lease_info*) | netman.drv |
| `reserved[0/1]` userconf 缓冲 | `srv.user.config`(ptr/size/状态打包结构) | firstinit.drv |
| `reserved[2]` login 成功标志 | `srv.auth.result` | login.drv |
| `reserved[3]` dev_mode | `srv.session.dev_mode` | session.drv |
| `g_mouse_state` / `mouse_poll_state()` | `srv.input.mouse.poll`(沿用 mouse_state_t magic/version 契约) | ps2mouse.drv |
| DSK 自带 FAT32 只读解析 + 写路径 | `srv.fs.fat32.read_path` / `srv.fs.fat32.write_file` / `srv.fs.fat32.bootlog` | fat32.drv(实装) |
| DSK 自带 ext4.c | `srv.fs.ext4.*` | ext4.drv(新) |
| DSK PIE ELF loader | (消灭)app 全变 .drv,统一走 UTSM DKM ET_REL loader | UTSM |
| dsk_fatal 莲花屏 | `api->log->panic`(内核 F1 莲花屏,视觉本就同源) | UTSM |
| dsk_boot_context 整体 | (消灭)P5 删除 dsk.h 中的定义 | — |
---
## 3. DSK 的命运:溶解
终态**完全消灭** deshab.elf。不保留"会话协调器特权模块"——会话排序逻辑移植为 session.drv,一个普通的 stage4 .drv,无任何特殊待遇。
迁移期(P2-P4)DSK 先降格为纯总线客户端(调度调用从"自带 FAT32 + PIE loader"改成 bus 调用),P5 删除二进制、dsk_loader.c 交接代码与 dsk_boot_context。
职责归位地图:
| DSK 职责 | 归宿 |
|---|---|
| FAT32 只读解析 + 写路径 + bootlog | fat32.drv 实装(母本:dsk_loader.c 的 fat32_read_path/write_file_in_dir 全套) |
| ext4.c 读写 | ext4.drv(整文件移植,dsk_fatal → g_log->panic) |
| PIE ELF loader + 8MB ibuf | 消灭(app 全变 .drv ET_REL;DKM-E70 ibuf 雷区整体绕开) |
| 静态 Logo / splash | session.drv |
| FUCK INI 读取 | 单一事实源 = Limine boot module(cmdline="fuck:config")+ session.drv 自带 INI 解析副本 |
| firstInit.txt 检测 | session.drv(经 srv.fs.fat32.read_path) |
| 模块调度(mouseInit/FirstInit/netman/login/shell/desktop/cmd) | 各自变 stage4 .drv;session.drv 用 kern.dkm.load_by_name 按需拉起 + bus 调 srv.*.run |
| BOOT01-07.TXT 里程碑 | `kern.bootlog.milestone` / srv.fs.fat32.bootlog |
| 会话选择(native/kde/cmd)+ 登录强制 | session.drv(登录失败 → SESSION-E02 panic,沿用 FS-E06 语义) |
| dsk_boot_context | 消灭 |
**P2-P5 之间的双 FAT32 实现是受控临时债**:deshab.elf 自身装载仍走内核侧 FAT32(`dsk_load_from_block_fat32`),直到 P5 删除。窗口期内禁止"顺手"修两边分叉逻辑。
---
## 4. 落地路线(P0-P6)
每 phase QEMU 可启动(build.bat -Variant dev → run_qemu.bat,ahci0 SATA + TCG + 串口 stdio),证据日志落 `.build_tmp/`。
### P0 — DSM 依赖图强制
`dkm/manifest.c`:capability 集合 + 不动点排序 + depends 校验(`DKM-E44`)。
验收:正常启动串口与基线逐行一致;负向测试(假 depends 条目)→ DKM-E44 莲花屏。
### P1 — 服务总线落地
`dkm/bus.c`(新)+ dkm.h 尾部追加 + provider 上下文 + `dsm_verify_provides`(DKM-E45)+ attest 翻绿 + selftest 用例(TST-E25..E28)+ devfs `/dev/services`。
验收:`[BUS] ready services=N`;`[TST] bus selftest PASS`;老 14 驱动不变。
### P2 — 文件系统归位
fat32.drv 实装(srv.fs.fat32.*)+ ext4.drv(srv.fs.ext4.*)+ DSK/UTSM 消费侧切总线。
验收:`[fat32] srv.fs.fat32.read_path registered`、`[ext4] selftest PASS`、首次启动全流程不回归。
### P3 — 加载器 FS 化 + stage4 + ps2mouse.drv 试点
DSM_MAX_STAGES 4→6 / PER_STAGE 8→12;`dsm_read_module_fs`(boot module 优先 / FS 回退 / `DKM-E46`);`kern.dkm.load_by_name` 接通;ps2mouse.drv(srv.input.mouse.poll);manifest 新增 stage4 "session";DSK 删 mouseInit 调度块。
验收:`[DSM] stage 4 session begin` → `[ps2mouse] driver ready`。
### P4 — 应用模块 DKM 化(4a-4f)
统一配方:① `dsk_entry(ctx)` → `driver_init(api, handle)` + driver_desc(stage=4、NO_UNLOAD);② 原 entry 主体改 `static <mod>_run(void)` 注册 `srv.<mod>.run`;③ ctx 消费点按 §2 迁移表替换;④ 自带 fatal → `api->log->panic`;⑤ 构建:PIE linker.ld 弃用,`clang -c + lld -r` 产出到 `SYSTEM/driver/session/`,**每模块必跑 `llvm-readobj --relocations` 核对 ∈ {R_X86_64_64/32/32S/PC32/PLT32}**;⑥ DSK 同 commit 删对应调度块改 bus 调 run。
子步:4a netman → 4b shell → 4c firstInit(user.conf 写盘收编进模块,reserved[0/1] 往返删除)→ 4d login → 4e desktop(~20 TU,最大风险点;host SDL 构建 #ifdef 隔离)→ 4f cmd + 收尾。
### P5 — DSK 退役 + session.drv
session.drv(排序骨架移植)+ 删 dsk_loader.c / dsk_boot_context / CODE/dsk/ + main.c 交接改 `dsm_load_by_manifest_upto(cfg, 4)`(quiesce 保留——运行时行为与 DSK 时代逐字节对齐,无回归)+ CLAUDE.md 全面更新。
验收:串口无 `[DSK] boot`;`[session] stage4 sequencing begin` → 全流程正常;dev/release 双过。
### P6 — 常驻调度 + 事件循环 + 真 IRQ 输入
sched_enable 常驻 + bootstrap park;desktop 任务化(task_create + 每帧 srv.input.*.poll + sleep_ms);ps2kbd 事件环形缓冲 + srv.input.kbd.poll;ps2mouse IRQ12 解屏蔽(kern.irq.unmask);firstInit/login 键盘轮询 → kbd.poll(强制:IRQ 驱动后 handler 读走 0x60,轮询端口会饿死)。
验收:`[SCHED] enable` 常驻;QEMU QMP sendkey/鼠标事件到达 desktop;`[desktop] task slot=N`。
### 收尾(并入 P6)
kapi 静态表退役(总线唯一注册源);block/net 注册表前端化(消费者切 `kern.block.*`);STUB grep 基线不抬升;desktop 任务 DRR 看门狗 register/kick(可选)。
---
## 5. 错误码登记
| 码 | 含义 | 触发点 |
|---|---|---|
| BUS-E01 | 服务名非法(无命名空间 / 模块注册 kern.* / 超长) | register_service |
| BUS-E02 | 服务重名 | register_service |
| BUS-E03 | 服务表满(DKM_BUS_MAX_SERVICES) | register_service |
| BUS-E04 | lookup 未命中(硬依赖未满足) | lookup |
| BUS-E05 | 注销违规(非 provider / F_NO_UNLOAD) | unregister_service |
| DKM-E44 | manifest depends 未满足 | dsm_load_stage_range / dsm_load_named |
| DKM-E45 | stage≥4 provides 未注册到总线 | dsm_verify_provides |
| DKM-E46 | 模块 boot module 与 FS 双源皆无 | dsm_load_stage_range |
| DKM-E47 | 依赖图成环 | 不动点排序 |
| DKM-E48 | capability 表满(DSM_MAX_CAPS) | dsm_capability_add |
| SESSION-E01 | session.drv 初始化失败(FUCK 缺失等) | session.drv |
| SESSION-E02 | 登录强制失败(沿用 FS-E06 语义) | session.drv |
| SESSION-E03 | 会话类型非法/加载失败 | session.drv |
| TST-E34..E38 | 总线 selftest 用例(注册/命中/probe/重名/注销违规;TST-E01..E33 已被既有用例占用) | utsm_selftest.c |
全部零降级:panic 莲花屏。
## 6. 设计内白名单(probe 型缺席 + 顺序豁免,CLAUDE.md 同步登记)
1. 无块设备时 `srv.fs.fat32.*` 缺席 → PE/会话路径 warn 跳过(环境能力缺失,与既有"块设备缺失回 boot module"白名单同源)。
2. FUCK `[drivers]` 关掉的模块 → 其 srv.* 服务缺席,消费方必须用 probe 并显式处理。
3. QEMU 无 ath9k / 无 wlan → 既有白名单不变。
4. **P0 顺序豁免**:`dsm_load_named_boot(cfg, "pci"/"ahci")`(kernel/main.c VMM 路径)跳过 depends 校验——pci+ahci 必须先于 apic/stage0 加载,否则 Linux guest 陷入 IDTR=0 VM-exit 风暴(历史验证的行为边界)。这是**顺序**豁免不是降级:模块照常 ELF 校验/driver_init/provides 登记,只是不卡依赖时序。`kern.dkm.load_by_name`(P3)一律走严格版 `dsm_load_named`。
## 7. 风险点
1. **desktop 多 TU 重定位集合**(最大技术风险):lld -r 产物可能带出新 relocation 类型 → DKM-E37 开机即炸(至少响亮)。每模块迁移必跑 readobj 并在 phase 记录贴清单。
2. **DSK-E70(ibuf 尾部写零,未解)**:DKM 化整体绕开 8MB ibuf,但若根因是 AHCI DMA PRDT 越界,会跟到 fat32.drv 缓冲。fat32/ext4 保留写后回读校验,持续观察 STATUS.md 该条目。
3. **交互式模块阻塞 bootstrap**:与今天行为等价无回归;DRR 看门狗默认关(FUCK),接 P6 时给 desktop 任务显式 register/kick。
4. **加载器重入**:loader 单线程不变式(§1.6),违反即契约违规。
5. **attest/FUCK 双面性**:app 模块进 manifest 后受 `[drivers]` 开关与 `require_*` 影响;build/configs/{dev,release}/FUCK 的 attest 豁免行同步增删(release 要求 desktop 必在,QEMU 无 ath9k 等继续豁免)。
6. **DSM/manifest 容量**:stage4 一期约 8 条 → P3 把上限提到 12/6;name[32]/path[64]/depends 4/provides 4,desktop 的 provides token 控制在 4 内。
---
> "没有主内核,每个模块都是内核——总线就是万物的神经。疯但互联。" 🪷
+39
View File
@@ -609,6 +609,45 @@ quiesce -> UTSM rollback -> device reset -> driver reinit -> resume
---
## 8.5 服务总线 ABI(万物互联 · D6/D7,2026-10-10 追加)
> 完整设计见 [万物互联与服务总线设计.md](./万物互联与服务总线设计.md)。本节只定 ABI 契约。
### 8.5.1 总线访问
`dkm_kernel_api` **尾部追加**(ABI 兼容,既有槽位偏移不变):
```c
const dkm_bus_api *bus; /* kapi 之后 */
```
总线结构(`dkm.h`):`dkm_bus_api { magic, version, register_service, unregister_service, lookup, probe, count, at }`,服务项 `dkm_bus_service { name[48], version, flags, fn, provider }`。
### 8.5.2 命名空间与注册规则
- `kern.*`:仅内核可注册(模块注册即 BUS-E01)。
- `srv.*`:任何 .drv 在 driver_init 里注册。**"运行"也是服务**:长期模块把原入口主体改为 `static void <mod>_run(void)` 并注册 `srv.<mod>.run`。
- 消费:硬依赖用 `lookup`(miss → BUS-E04 panic);能力缺席(设计内双路径)用 `probe`(miss 返回 -1,回退须登记 CLAUDE.md 白名单)。
### 8.5.3 生命周期契约
```text
driver_init(handle, api) = 初始化 + 注册 srv.*(+ 长期模块 task_create,此时抢占未启用)
运行 = 排序者(session.drv)bus 调 srv.*.run;一次性模块 call-and-return
DKM_F_NO_UNLOAD 模块的服务带 F_NO_UNLOAD,注销即 panic
loader 在 driver_init 前后设/清 current provider(provider 归属判定)
```
### 8.5.4 provides 校验(stage≥4)
stage≥4 模块的每个 manifest provides token `T`,driver_init 成功返回后必须已有 `srv.T` 或 `srv.T.*` 注册,否则 `DKM-E45` panic。stage0-3 老驱动豁免(provides 由内核注册表兑现,如 ahci→block registry)。同时 depends 自 P0 起被 loader 强制(miss → DKM-E44;依赖环 → DKM-E47)。
### 8.5.5 新错误码
`BUS-E01..E05`(名字非法/重名/表满/lookup 未命中/注销违规)、`DKM-E44..E47`(依赖未满足/未注册 provides/双源皆无/依赖环)——全部零降级 panic。
---
## 9. 第一版定稿
第一版驱动系统确定: