2026-07-02 15:40:39 +08:00
|
|
|
|
# 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
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-10-12 23:57:19 +08:00
|
|
|
|
## 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。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-07-02 15:40:39 +08:00
|
|
|
|
## 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。
|
|
|
|
|
|
```
|