Files
xyou f1a2a110d7 Record networking and DMA development progress
Add the current OS source tree, build scripts, system image layout, and development notes covering DMA page allocation, e1000 bring-up, net API dispatch, and DHCP work in progress.
2026-07-02 16:17:09 +08:00

692 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DKM 驱动模块系统
```text
DKM = Deshab Kernel Module
DSM = Driver Startup Manager
```
DKM 是 Deshab 内核的驱动模块系统,负责在内核启动时加载 `SYSTEM/driver` 下的 ELF64 `.drv` 驱动模块,并把驱动注册到内核服务体系中。
当前实现状态:CODE/UTSM 内核已接入完整 DKM/DSM 驱动加载系统。内置 `console_early` + manifest.json 解析 + Limine boot module 预加载 + 4 stage 分阶段加载。全部 14 个外部 `.drv` 已完成 ET_REL 装载全链路:ELF64 校验、符号扫描、section 拷贝到 arena、SHT_NOBITS 清零、R_X86_64_64/32/32S/PC32 重定位、driver_desc magic 校验、外部 driver_init 调用进入 ACTIVE。当前镜像还预加载 `driver/test.fat32` 作为 FAT32 驱动测试镜像。
Linux/Windows 已编译驱动不能直接作为 DKM 驱动使用。真实驱动必须按本文件定义的 DKM ABI 编译,导出 `driver_desc`、`driver_init`、`driver_exit`,并只通过 `dkm_kernel_api` 调用内核服务。
当前真实驱动进度:14/14。
```text
stage0: timer, apic, acpi, pci
stage1: console_fb, ahci, nvme, bootfs
stage2: vfs, devfs, fat32
stage3: ps2kbd, e1000, virtio_net
```
manifest 中 14 个外部 `.drv` 均已替换为真实 DKM 驱动并可加载执行。当前 IDT/PIC/IRQ 基础设施已在内核侧实现,`apic` 已完成 APIC discovery 并保留 PIC IRQ 路由,`ahci` 已完成 PCI/ABAR/HBA/port discovery,并通过 `kernel_api.dma.alloc_pages` 接入早期低位 DMA buffer,支持 SATA disk IDENTIFY 与 LBA0 READ 最小路径;识别 SATA disk 后可向 `kernel_api.block` 注册 `ahci0` block provider。`fat32` 已优先通过 block provider 读取 FAT32 镜像,无设备或 BPB 无效时回退 boot module。`nvme` 已完成 PCI discovery 并能识别 QEMU NVMe 控制器;由于当前 QEMU BAR0 位于 4G 以上,NVMe MMIO register 读取等待高位 PCI MMIO 映射能力。`ps2kbd` 和 `e1000` 已通过 `kernel_api.irq_register` 验证 IRQ handler 注册路径。`virtio_net` 已完成 PCI discovery 和 modern virtio capability 枚举,尚未进行 feature negotiation / virtqueue / RX-TX。
下一阶段 DKM/驱动路线:
```text
P0: 物理页分配器 + 页表/MMIO 映射接口
P1: DMA buffer/屏障约定 + AHCI/NVMe block 数据路径
P2: IDT 256 vectors + vector allocator + APIC/IOAPIC/MSI IRQ backend
P3: e1000 与 virtio_net RX/TX 数据路径
P4: FAT32 接入真实 block provider,替代 test.fat32 启动镜像
P5: 驱动 ABI 公共头、warning 清理、QEMU 场景自动化
```
---
## 1. 模块目标
DKM 的目标:
```text
1. 从 SYSTEM/driver/manifest.json 读取驱动清单。
2. 按 stage 分阶段加载驱动。
3. 支持 ELF64 .drv 模块加载和重定位。
4. 提供稳定的 driver_desc ABI。
5. 通过 dkm_kernel_api 向驱动暴露内核服务。
6. 支持 stage0/stage1 boot module 早期加载。
7. 将驱动内存纳入 UTSM。
8. 将驱动状态和恢复操作纳入 DRR。
```
---
## 2. 系统目录约定
打包为 IMG 后,`SYSTEM` 是系统根目录。
```text
SYSTEM/
boot/
utsm.elf
limine.conf
driver/
manifest.json
platform/
timer.drv
apic.drv
acpi.drv
bus/
pci.drv
block/
ahci.drv
nvme.drv
fs/
bootfs.drv
vfs.drv
fat32.drv
devfs.drv
net/
e1000.drv
virtio_net.drv
input/
ps2kbd.drv
console/
console_fb.drv
```
当前驱动清单:
```text
SYSTEM/driver/manifest.json
```
---
## 3. 启动阶段
DKM 使用分阶段加载。
```text
stage0: platform
timer / apic / acpi / pci
建立平台发现、中断、总线和基础计时能力。
stage1: boot
console / block / bootfs
建立启动日志、块设备和启动文件访问能力。
stage2: filesystem
vfs / fat32 / devfs
建立完整 VFS 和可挂载文件系统。
stage3: optional
net / input / gpu
加载网络、输入、图形等非启动关键驱动。
```
规则:
```text
1. stage0/stage1 可由 bootloader 预加载为 boot module。
2. stage2/stage3 默认从 SYSTEM/driver 加载。
3. required=true 的驱动失败时进入 DRR recovery 或 panic。
4. required=false 的驱动失败时标记 FAILED 并继续启动。
```
---
## 4. driver_desc ABI
每个 `.drv` 必须导出三个符号:
```text
driver_desc
driver_init
driver_exit
```
### 4.1 常量
```c
#define DKM_DRIVER_MAGIC 0x444B4D31u
#define DKM_ABI_VERSION 1
```
`0x444B4D31` 表示:
```text
DKM1
```
### 4.2 driver_desc 结构
```c
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;
};
```
### 4.3 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
```
### 4.4 flags
```text
DKM_F_REQUIRED
当前 stage 中失败则进入 DRR recovery 或 panic。
DKM_F_BOOT_MODULE
可由 bootloader 预加载。
DKM_F_NO_UNLOAD
不允许卸载。
DKM_F_STRONG_RECOVERY
驱动 data/bss 段使用 UTSM 强恢复策略。
DKM_F_DMA_REQUIRED
驱动需要 DMA API。
DKM_F_EARLY_LOG
驱动 init 期间允许使用 early log。
```
---
## 5. 驱动入口
```c
int driver_init(const struct dkm_kernel_api *api,
struct dkm_driver_handle *handle);
int driver_exit(struct dkm_driver_handle *handle);
```
约定:
```text
1. driver_init 返回 0 表示成功。
2. driver_init 返回负数表示失败。
3. driver_exit 仅用于非 DKM_F_NO_UNLOAD 驱动。
4. required 驱动失败会触发 DRR recovery 或 panic。
5. optional 驱动失败会被标记为 FAILED。
```
---
## 6. kernel_api ABI
驱动默认不直接依赖任意内核符号,而是通过 `dkm_kernel_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 void *mem;
const void *utsm;
const void *irq;
const void *pci;
const void *dma;
const void *vfs;
const void *net;
const void *timer;
const void *drr;
const void *rsdp_address;
const void *fb_address;
uint64_t fb_width;
uint64_t fb_height;
uint64_t fb_pitch;
uint16_t fb_bpp;
const void *boot_modules_response;
int (*irq_register)(uint8_t irq, void *handler);
uint64_t hhdm_offset;
};
```
### 6.1 log API
```c
struct dkm_log_api {
void (*info)(const char *msg);
void (*warn)(const char *msg);
void (*error)(const char *msg);
void (*panic)(const char *msg);
};
```
### 6.2 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);
};
```
### 6.3 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);
};
```
### 6.4 当前平台直通能力
当前内核已通过 `dkm_kernel_api` 直接暴露早期平台信息和 IRQ/HHDM 能力:
```text
rsdp_address Limine RSDP 地址,用于 ACPI 驱动
fb_address/width/height Limine framebuffer 信息,用于 console_fb
fb_pitch/fb_bpp framebuffer 行跨度和像素格式
boot_modules_response Limine module response,用于 bootfs/fat32 测试镜像
irq_register 注册 PIC IRQ0–15 handler,用于 ps2kbd/e1000
hhdm_offset physical → virtual direct map,用于 PCI BAR MMIO
```
### 6.5 IRQ / PCI / DMA 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);
};
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);
};
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);
};
```
---
## 7. ELF64 .drv Loader
第一版仅支持 x86_64 ELF64 小型内核模型。
### 7.1 必须支持的 relocation
```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 函数地址。
```
### 7.2 建议支持的 relocation
```text
R_X86_64_PC32
32-bit PC-relative 调用。
R_X86_64_PLT32
PLT-relative 调用。
R_X86_64_32 / R_X86_64_32S
仅允许确认地址范围安全时使用。
```
### 7.3 第一版禁止
```text
TLS relocation
IFUNC
lazy binding
外部动态库依赖
用户态 libc 依赖
异常展开表强依赖
```
### 7.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. 解析内核导出符号和 dkm_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。
```
---
## 8. manifest.json 格式
路径:
```text
SYSTEM/driver/manifest.json
```
顶层结构:
```json
{
"schema": "deshab.driver.manifest.v1",
"root": "SYSTEM",
"driverRoot": "SYSTEM/driver",
"format": "elf64-drv",
"abi": {},
"policy": {},
"stages": []
}
```
驱动项示例:
```json
{
"name": "pci",
"path": "driver/bus/pci.drv",
"class": "bus",
"required": true,
"depends": ["irq"],
"provides": ["pci"]
}
```
路径规则:
```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 加载。
```
---
## 9. 驱动加载状态机
正常加载:
```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
```
DRR 恢复状态:
```text
ACTIVE
-> SUSPENDED_BY_DRR
-> RECOVERING
-> REINITING
-> ACTIVE
```
---
## 10. DSM 加载策略
```text
DSM_LOAD_ALL()
1. 读取 SYSTEM/driver/manifest.json。
2. 校验 schema / abi / policy。
3. 按 stage 顺序加载。
4. 每个 stage 内按 priority 排序。
5. 检查 depends 是否已由 provides 满足。
6. 未满足依赖的驱动进入 DEP_WAIT。
7. 每轮加载成功后更新 provides set。
8. 一轮后仍 DEP_WAIT 的 required 驱动进入 FAILED_REQUIRED。
9. optional 驱动失败只记录状态。
```
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
```
---
## 11. stage0/stage1 boot module 方案
stage0/stage1 不应依赖普通 VFS。
bootloader 应预加载:
```text
SYSTEM/driver/manifest.json
SYSTEM/driver/platform/timer.drv
SYSTEM/driver/platform/acpi.drv
SYSTEM/driver/platform/apic.drv
SYSTEM/driver/bus/pci.drv
SYSTEM/driver/console/console_fb.drv
SYSTEM/driver/fs/bootfs.drv
SYSTEM/driver/test.fat32
```
可选预加载:
```text
SYSTEM/driver/block/ahci.drv
SYSTEM/driver/block/nvme.drv
SYSTEM/driver/fs/vfs.drv
SYSTEM/driver/fs/devfs.drv
SYSTEM/driver/fs/fat32.drv
SYSTEM/driver/net/e1000.drv
SYSTEM/driver/net/virtio_net.drv
SYSTEM/driver/input/ps2kbd.drv
```
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[];
};
```
查找规则:
```text
DSM_LOAD_DRIVER(path)
1. 如果 path 在 boot module table 中,直接从内存加载。
2. 否则如果 VFS 已可用,从 SYSTEM/path 加载。
3. 否则返回 BOOT_MODULE_NOT_FOUND。
```
---
## 12. 与 UTSM / DRR 的关系
### 12.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
```
### 12.2 DRR 记录项
```text
driver name
stage
state
module memory range
provided services
recovery ops
init result
last fault
```
### 12.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
```
---
## 13. 第一版实现清单
```text
1. manifest.json parser
2. boot module table lookup
3. ELF64 header 校验
4. ELF64 section/program loading
5. relocation 处理
6. driver_desc 校验
7. kernel_api table 初始化
8. depends/provides resolver
9. staged loader
10. driver state table
11. DRR driver fault reporting
12. UTSM module memory allocation
```
---
## 14. 相关文件
```text
SYSTEM/driver/manifest.json
驱动启动清单。
RE/驱动模块ABI设计.md
DKM ABI 详细设计。
CODE/UTSM/README.md
UTSM 与驱动加载的整合说明。
```