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:
@@ -414,7 +414,9 @@ int dkm_load_elf_rel(const void *address, u64 size, const struct dkm_symbol_scan
|
||||
handle.flags = desc->flags;
|
||||
|
||||
dkm_log_set_driver(desc->name); /* D4: 驱动自己的颜色 */
|
||||
dkm_bus_set_current_provider(&handle); /* D6: 总线 provider 上下文 */
|
||||
int result = init(dkm_get_kernel_api(), &handle);
|
||||
dkm_bus_set_current_provider(0);
|
||||
dkm_log_set_driver(0);
|
||||
handle.init_status = result;
|
||||
if (result != 0) {
|
||||
|
||||
@@ -0,0 +1,318 @@
|
||||
/* ===================================================================
|
||||
* D6 万物互联:dkm_bus 双向服务总线
|
||||
*
|
||||
* "没有主内核,每个模块都是内核——总线就是万物的神经。"
|
||||
*
|
||||
* kapi(kernel_api.c)是内核→模块的单向只读导出表;本文件把它双向化:
|
||||
* 任何 .drv 模块在 driver_init 里注册 srv.* 服务,任何模块按名消费。
|
||||
* kern.* 仅内核可注册(provider==NULL 时),srv.* 仅模块可注册。
|
||||
*
|
||||
* 失败策略(铁律映射):
|
||||
* register 名字非法/身份不符 → BUS-E01 panic(编程错误)
|
||||
* register 重名 → BUS-E02 panic
|
||||
* register 表满 → BUS-E03 panic
|
||||
* lookup 未命中 → BUS-E04 panic(硬依赖未满足=编程错误)
|
||||
* unregister 违规 → BUS-E05 panic
|
||||
* probe 未命中 → 返回 -1(能力缺席=设计内双路径,白名单)
|
||||
*
|
||||
* 设计定稿:docs/RE/万物互联与服务总线设计.md §1。
|
||||
* =================================================================== */
|
||||
|
||||
#include <utsm/dkm.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/idt.h>
|
||||
#include <utsm/mm.h>
|
||||
#include <utsm/dma.h>
|
||||
#include <utsm/drr.h>
|
||||
#include <utsm/utrw.h>
|
||||
#include <utsm/block.h>
|
||||
#include <utsm/pe.h>
|
||||
#include <utsm/linux_compat.h>
|
||||
#include "../kernel/ini_parser.h"
|
||||
|
||||
/* manifest.c 提供;签名见 dkm.h 头注释(避免头依赖) */
|
||||
void dsm_load_named(const ini_config *cfg, const char *name);
|
||||
/* kernel/main.c 提供:FUCK 启动配置只读访问(g_boot_cfg) */
|
||||
const ini_config *utsm_boot_cfg_get(void);
|
||||
|
||||
static dkm_bus_service g_services[DKM_BUS_MAX_SERVICES];
|
||||
static u32 g_service_count;
|
||||
static struct dkm_driver_handle *g_current_provider; /* NULL = 内核 */
|
||||
|
||||
/* ---- 名字工具 ---- */
|
||||
|
||||
static int bus_streq(const char *a, const char *b) {
|
||||
usize i = 0;
|
||||
while (a[i] && b[i]) {
|
||||
if (a[i] != b[i]) return 0;
|
||||
i++;
|
||||
}
|
||||
return a[i] == b[i];
|
||||
}
|
||||
|
||||
static int bus_prefix_of(const char *s, const char *prefix) {
|
||||
usize i = 0;
|
||||
while (prefix[i]) {
|
||||
if (s[i] != prefix[i]) return 0;
|
||||
i++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_find(const char *name) {
|
||||
for (u32 i = 0; i < g_service_count; i++) {
|
||||
if (bus_streq(g_services[i].name, name)) return (int)i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---- 总线原语(BUS-E 全部 panic,零降级) ---- */
|
||||
|
||||
static int bus_register_impl(const char *name, u32 version, void *fn) {
|
||||
if (!name || !fn || !name[0]) {
|
||||
panic_full("BUS-E01 INVALID SERVICE NAME",
|
||||
"dkm_bus: null/empty service name or fn", 0);
|
||||
return -1;
|
||||
}
|
||||
usize len = 0;
|
||||
while (name[len]) {
|
||||
if (len >= DKM_BUS_MAX_NAME) {
|
||||
log_error("[BUS] name too long: ");
|
||||
log_info(name);
|
||||
panic_full("BUS-E01 INVALID SERVICE NAME",
|
||||
"dkm_bus: service name exceeds DKM_BUS_MAX_NAME", 0);
|
||||
return -1;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
int is_kern = bus_prefix_of(name, "kern.");
|
||||
int is_srv = bus_prefix_of(name, "srv.");
|
||||
if (!is_kern && !is_srv) {
|
||||
log_error("[BUS] name without namespace prefix: ");
|
||||
log_info(name);
|
||||
panic_full("BUS-E01 INVALID SERVICE NAME",
|
||||
"dkm_bus: service name must start with kern. or srv.", 0);
|
||||
return -1;
|
||||
}
|
||||
if (is_kern && g_current_provider != 0) {
|
||||
log_error("[BUS] module tried to register kern.*: ");
|
||||
log_info(name);
|
||||
panic_full("BUS-E01 INVALID SERVICE NAME",
|
||||
"dkm_bus: only the kernel may register kern.* services", 0);
|
||||
return -1;
|
||||
}
|
||||
if (is_srv && g_current_provider == 0) {
|
||||
log_error("[BUS] kernel tried to register srv.*: ");
|
||||
log_info(name);
|
||||
panic_full("BUS-E01 INVALID SERVICE NAME",
|
||||
"dkm_bus: kernel services must use the kern.* namespace", 0);
|
||||
return -1;
|
||||
}
|
||||
if (bus_find(name) >= 0) {
|
||||
log_error("[BUS] duplicate service: ");
|
||||
log_info(name);
|
||||
panic_full("BUS-E02 DUPLICATE SERVICE",
|
||||
"dkm_bus: service name already registered", 0);
|
||||
return -1;
|
||||
}
|
||||
if (g_service_count >= DKM_BUS_MAX_SERVICES) {
|
||||
panic_full("BUS-E03 SERVICE TABLE FULL",
|
||||
"dkm_bus: g_services overflow (DKM_BUS_MAX_SERVICES)", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dkm_bus_service *s = &g_services[g_service_count];
|
||||
for (usize i = 0; i < len; i++) s->name[i] = name[i];
|
||||
s->name[len] = 0;
|
||||
s->version = version;
|
||||
s->fn = fn;
|
||||
/* 存 desc 而非 handle:loader 的 handle 是栈局部(init 返回即悬垂),
|
||||
* desc 在驱动镜像内存里持久;注销校验按 desc 指针判身份。 */
|
||||
s->provider = g_current_provider ? g_current_provider->desc : 0;
|
||||
if (is_kern) {
|
||||
s->flags = DKM_BUS_F_KERNEL;
|
||||
} else if (g_current_provider && (g_current_provider->flags & DKM_F_NO_UNLOAD)) {
|
||||
s->flags = DKM_BUS_F_NO_UNLOAD;
|
||||
} else {
|
||||
s->flags = 0;
|
||||
}
|
||||
g_service_count++;
|
||||
|
||||
log_info("[BUS] service registered: ");
|
||||
log_info(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bus_unregister_impl(const char *name) {
|
||||
int idx = name ? bus_find(name) : -1;
|
||||
if (idx < 0) {
|
||||
log_error("[BUS] unregister unknown service: ");
|
||||
log_info(name ? name : "(null)");
|
||||
panic_full("BUS-E05 UNREGISTER VIOLATION",
|
||||
"dkm_bus: unregister of unknown service", 0);
|
||||
return -1;
|
||||
}
|
||||
dkm_bus_service *s = &g_services[idx];
|
||||
if (s->flags & (DKM_BUS_F_KERNEL | DKM_BUS_F_NO_UNLOAD)) {
|
||||
log_error("[BUS] unregister of permanent service: ");
|
||||
log_info(name);
|
||||
panic_full("BUS-E05 UNREGISTER VIOLATION",
|
||||
"dkm_bus: F_KERNEL/F_NO_UNLOAD service cannot be unregistered", 0);
|
||||
return -1;
|
||||
}
|
||||
if (s->provider != (g_current_provider ? g_current_provider->desc : 0)) {
|
||||
log_error("[BUS] unregister by non-provider: ");
|
||||
log_info(name);
|
||||
panic_full("BUS-E05 UNREGISTER VIOLATION",
|
||||
"dkm_bus: only the provider may unregister its service", 0);
|
||||
return -1;
|
||||
}
|
||||
/* 紧缩(顺序无关紧要,表小) */
|
||||
for (u32 i = (u32)idx; i + 1 < g_service_count; i++) {
|
||||
g_services[i] = g_services[i + 1];
|
||||
}
|
||||
g_service_count--;
|
||||
log_info("[BUS] service unregistered: ");
|
||||
log_info(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bus_lookup_impl(const char *name, void **out_fn, u32 *out_version) {
|
||||
int idx = name ? bus_find(name) : -1;
|
||||
if (idx < 0) {
|
||||
log_error("[BUS] lookup miss: ");
|
||||
log_info(name ? name : "(null)");
|
||||
panic_full("BUS-E04 LOOKUP MISS",
|
||||
"dkm_bus: required service not registered (hard dependency)", 0);
|
||||
return -1;
|
||||
}
|
||||
if (out_fn) *out_fn = g_services[idx].fn;
|
||||
if (out_version) *out_version = g_services[idx].version;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bus_probe_impl(const char *name, void **out_fn, u32 *out_version) {
|
||||
int idx = name ? bus_find(name) : -1;
|
||||
if (idx < 0) return -1;
|
||||
if (out_fn) *out_fn = g_services[idx].fn;
|
||||
if (out_version) *out_version = g_services[idx].version;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 bus_count_impl(void) {
|
||||
return g_service_count;
|
||||
}
|
||||
|
||||
static const dkm_bus_service *bus_at_impl(u32 index) {
|
||||
if (index >= g_service_count) return 0;
|
||||
return &g_services[index];
|
||||
}
|
||||
|
||||
static const dkm_bus_api g_bus_api = {
|
||||
.magic = DKM_BUS_MAGIC,
|
||||
.version = DKM_BUS_VERSION,
|
||||
.register_service = bus_register_impl,
|
||||
.unregister_service = bus_unregister_impl,
|
||||
.lookup = bus_lookup_impl,
|
||||
.probe = bus_probe_impl,
|
||||
.count = bus_count_impl,
|
||||
.at = bus_at_impl,
|
||||
};
|
||||
|
||||
const dkm_bus_api *dkm_bus_get_api(void) {
|
||||
return &g_bus_api;
|
||||
}
|
||||
|
||||
void dkm_bus_set_current_provider(struct dkm_driver_handle *h) {
|
||||
g_current_provider = h;
|
||||
}
|
||||
|
||||
int dkm_bus_prefix_registered(const char *prefix) {
|
||||
if (!prefix) return 0;
|
||||
usize len = 0;
|
||||
while (prefix[len]) len++;
|
||||
for (u32 i = 0; i < g_service_count; i++) {
|
||||
const char *n = g_services[i].name;
|
||||
if (bus_streq(n, prefix)) return 1;
|
||||
/* 前缀命中:n == "prefix.xxx" */
|
||||
if (bus_prefix_of(n, prefix) && n[len] == '.') return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ===================================================================
|
||||
* kern.* 播种
|
||||
*
|
||||
* kapi 14 条(log.* dma/irq/mm/apic/drr/utrw)以 kern. 前缀重新播种
|
||||
* (旧无前缀 kapi 名冻结不动,兼容层);另加 block/pe/lxc/probe/config/
|
||||
* load_by_name。dsk_boot_context.reserved[] 的逐槽替代服务(srv.*)随
|
||||
* P2-P4 各模块落地注册,本表不抢跑。
|
||||
* kern.probe.info 随 P4b(shell 消费方)落地;kern.bootlog.milestone
|
||||
* 随 P2(fat32.drv 实装)落地。
|
||||
* =================================================================== */
|
||||
|
||||
static void bus_kern_panic(const char *msg) {
|
||||
panic_full("DKM-PANIC", msg, 0);
|
||||
}
|
||||
|
||||
static int bus_kern_load_by_name(const char *name) {
|
||||
/* P3 接线后带 FUCK cfg 过滤;当前调用方(内部)走 manifest 语义。 */
|
||||
dsm_load_named(0, name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *bus_kern_config_get(const char *section, const char *key) {
|
||||
const ini_config *cfg = utsm_boot_cfg_get();
|
||||
if (!cfg) return 0;
|
||||
return ini_get(cfg, section, key);
|
||||
}
|
||||
|
||||
static int bus_seed(const char *name, void *fn) {
|
||||
return bus_register_impl(name, 1u, fn);
|
||||
}
|
||||
|
||||
void dkm_bus_init(void) {
|
||||
static int s_inited = 0;
|
||||
if (s_inited) return;
|
||||
s_inited = 1;
|
||||
|
||||
g_service_count = 0;
|
||||
g_current_provider = 0;
|
||||
|
||||
/* log(kapi 4 条迁移) */
|
||||
bus_seed("kern.log.info", (void *)log_info);
|
||||
bus_seed("kern.log.warn", (void *)log_warn);
|
||||
bus_seed("kern.log.error", (void *)log_error);
|
||||
bus_seed("kern.log.panic", (void *)bus_kern_panic);
|
||||
/* dma / irq / mm / apic(kapi 迁移 + P6 真 IRQ 输入新增 unmask/mask) */
|
||||
bus_seed("kern.dma.alloc_pages", (void *)dma_alloc_pages);
|
||||
bus_seed("kern.irq.register", (void *)irq_register);
|
||||
bus_seed("kern.irq.vector_alloc", (void *)irq_vector_alloc);
|
||||
bus_seed("kern.irq.vector_free", (void *)irq_vector_free);
|
||||
bus_seed("kern.irq.unmask", (void *)pic_irq_unmask);
|
||||
bus_seed("kern.irq.mask", (void *)pic_irq_mask);
|
||||
bus_seed("kern.mm.map_mmio", (void *)mm_map_mmio);
|
||||
bus_seed("kern.mm.unmap_mmio", (void *)mm_unmap_mmio);
|
||||
bus_seed("kern.apic.register_eoi", (void *)idt_register_apic_eoi);
|
||||
/* drr / utrw(kapi 迁移) */
|
||||
bus_seed("kern.drr.snapshot_dirty", (void *)drr_ckpt_snapshot_dirty);
|
||||
bus_seed("kern.drr.rollback_pages", (void *)drr_rollback_pages);
|
||||
bus_seed("kern.utrw.debug_dump", (void *)utrw_debug_dump_page);
|
||||
/* block registry 前端(替代 desktop 的 api+0xA8 裸偏移读) */
|
||||
{
|
||||
const dkm_block_api *b = block_get_api();
|
||||
bus_seed("kern.block.read", (void *)b->read);
|
||||
bus_seed("kern.block.write", (void *)b->write);
|
||||
}
|
||||
/* PE / Linux 兼容层服务(替代 reserved[4]/reserved[5]) */
|
||||
bus_seed("kern.pe.service", (void *)pe_get_service);
|
||||
bus_seed("kern.lxc.service", (void *)linux_compat_get_service);
|
||||
/* 按名加载(session.drv 的排序拉手,P3 接 FUCK 过滤) */
|
||||
bus_seed("kern.dkm.load_by_name", (void *)bus_kern_load_by_name);
|
||||
/* FUCK 配置只读访问(替代 reserved[] 内散落的配置回传) */
|
||||
bus_seed("kern.config.get", (void *)bus_kern_config_get);
|
||||
|
||||
log_info("[BUS] ready services=");
|
||||
log_hex64("[BUS] count=", g_service_count);
|
||||
}
|
||||
@@ -21,11 +21,9 @@ static void dkm_api_error(const char *msg) {
|
||||
}
|
||||
|
||||
static void dkm_api_panic(const char *msg) {
|
||||
/* F1: 驱动 panic 统一走莲花崩溃屏(串口 dump + DRR 归档 + 帧缓冲) */
|
||||
/* F1: 驱动 panic 统一走莲花崩溃屏(串口 dump + DRR 归档 + 帧缓冲)。
|
||||
* fallback 模式下返回驱动,由驱动调用点走其备用路径。 */
|
||||
panic_full("DKM-PANIC", msg, 0);
|
||||
for (;;) {
|
||||
__asm__ volatile("cli; hlt");
|
||||
}
|
||||
}
|
||||
|
||||
static const dkm_log_api g_log_api = {
|
||||
@@ -85,7 +83,8 @@ static dkm_kernel_api g_kernel_api = {
|
||||
.mm_unmap_mmio = 0,
|
||||
.register_apic_eoi = 0,
|
||||
.sched = 0,
|
||||
.kapi = 0
|
||||
.kapi = 0,
|
||||
.bus = 0
|
||||
};
|
||||
|
||||
const dkm_kernel_api *dkm_get_kernel_api(void) {
|
||||
@@ -142,6 +141,11 @@ extern volatile struct limine_module_request g_module_request;
|
||||
extern volatile struct limine_hhdm_request g_hhdm_request;
|
||||
|
||||
void dkm_fill_platform_info(void) {
|
||||
/* D6 万物互联:总线先播种再挂载(必须先于一切驱动加载——
|
||||
* driver_init 里即可 api->bus->register_service)。 */
|
||||
dkm_bus_init();
|
||||
g_kernel_api.bus = dkm_bus_get_api();
|
||||
|
||||
g_kernel_api.dma = dma_get_api();
|
||||
g_kernel_api.net = net_get_api();
|
||||
g_kernel_api.block = block_get_api();
|
||||
@@ -206,4 +210,4 @@ void dkm_sipi_wake_ap(u32 lapic_id, u64 entry_eip) {
|
||||
(void)lapic_id; (void)entry_eip;
|
||||
panic_full("DKM-E03 SIPI AP WAKE NOT IMPLEMENTED",
|
||||
"AP startup framework: designed, not implemented (BSP-only)", 0);
|
||||
}
|
||||
}
|
||||
|
||||
+242
-53
@@ -12,6 +12,7 @@ void dsm_load_by_manifest_ex(const ini_config *cfg);
|
||||
#define DSM_MAX_STAGES 4
|
||||
#define DSM_MAX_DEPENDS 4
|
||||
#define DSM_MAX_PROVIDES 4
|
||||
#define DSM_MAX_CAPS 128
|
||||
|
||||
typedef struct dsm_driver_entry {
|
||||
char name[32];
|
||||
@@ -24,6 +25,9 @@ typedef struct dsm_driver_entry {
|
||||
u32 provide_count;
|
||||
struct limine_file *boot_module;
|
||||
int loaded;
|
||||
/* P0(万物互联):终态标志——已加载/被 FUCK 关闭/模块缺失/加载失败,
|
||||
* 不再是本轮不动点迭代的候选。resolved 但 !loaded 的驱动不登记 provides。 */
|
||||
int resolved;
|
||||
} dsm_driver_entry;
|
||||
|
||||
typedef struct dsm_stage_entry {
|
||||
@@ -37,6 +41,119 @@ typedef struct dsm_stage_entry {
|
||||
static dsm_stage_entry g_stages[DSM_MAX_STAGES];
|
||||
static u32 g_stage_count;
|
||||
|
||||
static int streq_static(const char *a, const char *b);
|
||||
|
||||
/* ===================================================================
|
||||
* P0(万物互联):DSM 依赖图强制
|
||||
*
|
||||
* capability 集合 = 已成功加载驱动的 provides token 并集。
|
||||
* 加载前校验 depends 全满足(miss → DKM-E44);
|
||||
* 同 stage 内按依赖不动点迭代(环 → DKM-E47)。
|
||||
* 性能不是目标(多趟扫描),正确性第一——设计定稿见
|
||||
* docs/RE/万物互联与服务总线设计.md §1.5。
|
||||
* =================================================================== */
|
||||
static char g_caps[DSM_MAX_CAPS][32];
|
||||
static u32 g_cap_count;
|
||||
|
||||
static int dsm_capability_satisfied(const char *token) {
|
||||
for (u32 i = 0; i < g_cap_count; i++) {
|
||||
if (streq_static(g_caps[i], token)) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dsm_capability_add(const char *token) {
|
||||
if (dsm_capability_satisfied(token)) return;
|
||||
if (g_cap_count >= DSM_MAX_CAPS) {
|
||||
panic_full("DKM-E48 CAPABILITY TABLE FULL",
|
||||
"P0 dependency graph: g_caps overflow (DSM_MAX_CAPS)", 0);
|
||||
return;
|
||||
}
|
||||
for (u32 i = 0; i + 1 < 32 && token[i]; i++) {
|
||||
g_caps[g_cap_count][i] = token[i];
|
||||
}
|
||||
g_caps[g_cap_count][31] = 0;
|
||||
g_cap_count++;
|
||||
}
|
||||
|
||||
static void dsm_register_provides(const dsm_driver_entry *drv) {
|
||||
for (u32 i = 0; i < drv->provide_count; i++) {
|
||||
dsm_capability_add(drv->provides[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* P1(万物互联):stage>=4 的 provides 总线契约校验——driver_init 成功后,
|
||||
* 每个 provides token T 必须已有 "srv.T" 或 "srv.T.*" 服务注册到总线,
|
||||
* 否则 DKM-E45(零降级:provides 是对消费者/排序者的承诺,注册不到即违约)。
|
||||
* stage0-3 老 14 驱动豁免:其 provides 由内核注册表兑现(ahci→block
|
||||
* registry 等),不经总线。豁免清单 = manifest.json 现有 stage0-3 全部条目。 */
|
||||
static void dsm_verify_provides(const dsm_stage_entry *stage, const dsm_driver_entry *drv) {
|
||||
if (stage->id < 4) return;
|
||||
for (u32 i = 0; i < drv->provide_count; i++) {
|
||||
char srv_name[40];
|
||||
const char *token = drv->provides[i];
|
||||
srv_name[0] = 's'; srv_name[1] = 'r'; srv_name[2] = 'v'; srv_name[3] = '.';
|
||||
u32 p = 4;
|
||||
while (token[p - 4] && p + 1 < sizeof(srv_name)) {
|
||||
srv_name[p] = token[p - 4];
|
||||
p++;
|
||||
}
|
||||
srv_name[p] = 0;
|
||||
if (!dkm_bus_prefix_registered(srv_name)) {
|
||||
log_error("[DSM] provides token not registered on bus: ");
|
||||
log_info(drv->name);
|
||||
log_info(token);
|
||||
panic_full("DKM-E45 PROVIDES NOT REGISTERED",
|
||||
"stage>=4 driver provides token has no matching srv.* bus service", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* depends 全满足返回 1;否则返回 0 并(可选)写出第一个未满足 token 的下标 */
|
||||
static int dsm_deps_satisfied(const dsm_driver_entry *drv, u32 *missing_idx) {
|
||||
for (u32 i = 0; i < drv->depend_count; i++) {
|
||||
if (!dsm_capability_satisfied(drv->depends[i])) {
|
||||
if (missing_idx) *missing_idx = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* token 是否由本 stage 尚未 resolved 的候选提供(用于区分缺依赖 vs 成环) */
|
||||
static int dsm_dep_pending_in_stage(const dsm_stage_entry *stage, const char *token) {
|
||||
for (u32 di = 0; di < stage->driver_count; di++) {
|
||||
const dsm_driver_entry *drv = &stage->drivers[di];
|
||||
if (drv->resolved) continue;
|
||||
for (u32 i = 0; i < drv->provide_count; i++) {
|
||||
if (streq_static(drv->provides[i], token)) return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 不动点停滞:先判真缺依赖(DKM-E44),全在剩余候选里则判环(DKM-E47)。
|
||||
* 零降级:两者都是编程/manifest 错误,莲花屏。 */
|
||||
static void dsm_report_dependency_stall(const dsm_stage_entry *stage) {
|
||||
for (u32 di = 0; di < stage->driver_count; di++) {
|
||||
const dsm_driver_entry *drv = &stage->drivers[di];
|
||||
if (drv->resolved) continue;
|
||||
for (u32 i = 0; i < drv->depend_count; i++) {
|
||||
const char *dep = drv->depends[i];
|
||||
if (!dsm_capability_satisfied(dep) && !dsm_dep_pending_in_stage(stage, dep)) {
|
||||
log_error("[DSM] dependency not satisfied: ");
|
||||
log_info(drv->name);
|
||||
log_info(dep);
|
||||
panic_full("DKM-E44 DEPENDENCY NOT SATISFIED",
|
||||
"manifest depends token not provided by any loaded/pending driver", 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
panic_full("DKM-E47 DEPENDENCY CYCLE",
|
||||
"manifest stage dependency graph has a cycle (no progress)", 0);
|
||||
}
|
||||
|
||||
extern volatile struct limine_module_request g_module_request;
|
||||
|
||||
static int dsm_skip_ws(const char **p) {
|
||||
@@ -136,6 +253,7 @@ static void dsm_parse_driver(const char **p, dsm_driver_entry *drv) {
|
||||
drv->required = 1;
|
||||
drv->boot_module = 0;
|
||||
drv->loaded = 0;
|
||||
drv->resolved = 0;
|
||||
drv->class_id = 0;
|
||||
|
||||
if (dsm_expect(p, '{') != 0) return;
|
||||
@@ -345,70 +463,115 @@ static void dsm_load_stage_range(const ini_config *cfg, int limit_stage, u32 max
|
||||
log_info(stage->name);
|
||||
log_hex64("[DSM] driver count=", stage->driver_count);
|
||||
|
||||
/* P0:同 stage 内按依赖不动点迭代——每趟加载 deps 已满足的候选,
|
||||
* 直到全部 resolved;停滞即 DKM-E44/E47(见 dsm_report_dependency_stall)。
|
||||
* 多趟扫描 O(n²·趟数),性能刻意不管,正确性第一。 */
|
||||
u32 pending = 0;
|
||||
for (u32 di = 0; di < stage->driver_count; di++) {
|
||||
dsm_driver_entry *drv = &stage->drivers[di];
|
||||
struct limine_file *f;
|
||||
struct dkm_symbol_scan symbols;
|
||||
int result;
|
||||
if (!stage->drivers[di].resolved) pending++;
|
||||
}
|
||||
|
||||
if (drv->loaded) continue;
|
||||
while (pending > 0) {
|
||||
u32 pending_before = pending;
|
||||
|
||||
/* === FUCK [drivers] 驱动开关检查 === */
|
||||
if (cfg) {
|
||||
int enabled = ini_get_bool(cfg, "drivers", drv->name, 1);
|
||||
if (!enabled) {
|
||||
log_info("[DSM] driver disabled by FUCK: ");
|
||||
for (u32 di = 0; di < stage->driver_count; di++) {
|
||||
dsm_driver_entry *drv = &stage->drivers[di];
|
||||
struct limine_file *f;
|
||||
struct dkm_symbol_scan symbols;
|
||||
int result;
|
||||
|
||||
if (drv->resolved) continue;
|
||||
|
||||
/* === FUCK [drivers] 驱动开关检查 ===
|
||||
* 关闭即退出候选(provides 不登记,依赖它的模块将 DKM-E44)。 */
|
||||
if (cfg) {
|
||||
int enabled = ini_get_bool(cfg, "drivers", drv->name, 1);
|
||||
if (!enabled) {
|
||||
log_info("[DSM] driver disabled by FUCK: ");
|
||||
log_info(drv->name);
|
||||
drv->resolved = 1;
|
||||
pending--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* P0:depends 校验——暂不满足先跳过,等本 stage 后续候选登记
|
||||
* provides 后下一趟重试;整体停滞时统一判罚(零降级)。 */
|
||||
if (!dsm_deps_satisfied(drv, 0)) continue;
|
||||
|
||||
drv->boot_module = dsm_find_boot_module(drv->path);
|
||||
if (!drv->boot_module) {
|
||||
log_info("[DSM] module not found");
|
||||
log_info(drv->name);
|
||||
drv->resolved = 1;
|
||||
pending--;
|
||||
if (drv->required && stage->required) {
|
||||
/* 严格错误策略插桩:required 驱动缺模块零降级(DKM-E04) */
|
||||
panic_full("DKM-E04 REQUIRED DRIVER MODULE MISSING",
|
||||
"required driver boot module not found in manifest stage", 0);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
drv->boot_module = dsm_find_boot_module(drv->path);
|
||||
if (!drv->boot_module) {
|
||||
log_info("[DSM] module not found");
|
||||
f = drv->boot_module;
|
||||
log_info("[DSM] loading driver");
|
||||
log_info(drv->name);
|
||||
if (drv->required && stage->required) {
|
||||
/* 严格错误策略插桩:required 驱动缺模块零降级(DKM-E04) */
|
||||
panic_full("DKM-E04 REQUIRED DRIVER MODULE MISSING",
|
||||
"required driver boot module not found in manifest stage", 0);
|
||||
break;
|
||||
|
||||
if (dkm_check_elf64(f->address, f->size) != 0) {
|
||||
log_error("[DSM] ELF check failed");
|
||||
if (drv->required && stage->required) {
|
||||
panic_full("DKM-E05 REQUIRED DRIVER ELF INVALID",
|
||||
"required driver boot module failed ELF64 check", 0);
|
||||
}
|
||||
drv->resolved = 1;
|
||||
pending--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dkm_scan_symbols(f->address, f->size, &symbols) != 0) {
|
||||
log_error("[DSM] symbol scan failed");
|
||||
if (drv->required && stage->required) {
|
||||
panic_full("DKM-E06 REQUIRED DRIVER SYMBOL SCAN FAILED",
|
||||
"required driver symbol scan failed", 0);
|
||||
}
|
||||
drv->resolved = 1;
|
||||
pending--;
|
||||
continue;
|
||||
}
|
||||
|
||||
result = dkm_load_elf_rel(f->address, f->size, &symbols);
|
||||
if (result != 0) {
|
||||
log_error("[DSM] load failed");
|
||||
if (drv->required && stage->required) {
|
||||
/* 严格错误策略插桩:required 驱动加载失败零降级(DKM-E07) */
|
||||
panic_full("DKM-E07 REQUIRED DRIVER LOAD FAILED",
|
||||
"required driver relocation/load failed", 0);
|
||||
}
|
||||
drv->resolved = 1;
|
||||
pending--;
|
||||
} else {
|
||||
drv->loaded = 1;
|
||||
drv->resolved = 1;
|
||||
pending--;
|
||||
/* P0:加载成功才登记 provides(disabled/missing/failed 一律不登记) */
|
||||
dsm_register_provides(drv);
|
||||
/* P1:stage>=4 provides 总线契约校验(DKM-E45) */
|
||||
dsm_verify_provides(stage, drv);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
f = drv->boot_module;
|
||||
log_info("[DSM] loading driver");
|
||||
log_info(drv->name);
|
||||
|
||||
if (dkm_check_elf64(f->address, f->size) != 0) {
|
||||
log_error("[DSM] ELF check failed");
|
||||
if (drv->required && stage->required) {
|
||||
panic_full("DKM-E05 REQUIRED DRIVER ELF INVALID",
|
||||
"required driver boot module failed ELF64 check", 0);
|
||||
if (pending > 0 && pending == pending_before) {
|
||||
/* 一整趟零进展:真缺依赖(DKM-E44)或依赖环(DKM-E47) */
|
||||
dsm_report_dependency_stall(stage);
|
||||
/* fallback:停滞的候选全部放弃(不登记 provides),结束本 stage */
|
||||
for (u32 di = 0; di < stage->driver_count; di++) {
|
||||
if (stage->drivers[di].resolved) continue;
|
||||
log_warn("[DSM] fallback: driver skipped (unresolved deps): ");
|
||||
log_info(stage->drivers[di].name);
|
||||
stage->drivers[di].resolved = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dkm_scan_symbols(f->address, f->size, &symbols) != 0) {
|
||||
log_error("[DSM] symbol scan failed");
|
||||
if (drv->required && stage->required) {
|
||||
panic_full("DKM-E06 REQUIRED DRIVER SYMBOL SCAN FAILED",
|
||||
"required driver symbol scan failed", 0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
result = dkm_load_elf_rel(f->address, f->size, &symbols);
|
||||
if (result != 0) {
|
||||
log_error("[DSM] load failed");
|
||||
if (drv->required && stage->required) {
|
||||
/* 严格错误策略插桩:required 驱动加载失败零降级(DKM-E07) */
|
||||
panic_full("DKM-E07 REQUIRED DRIVER LOAD FAILED",
|
||||
"required driver relocation/load failed", 0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
drv->loaded = 1;
|
||||
pending = 0;
|
||||
}
|
||||
}
|
||||
log_info("[DSM] stage end");
|
||||
@@ -419,7 +582,12 @@ void dsm_load_by_manifest_upto(const ini_config *cfg, u32 max_stage_id) {
|
||||
dsm_load_stage_range(cfg, 1, max_stage_id);
|
||||
}
|
||||
|
||||
void dsm_load_named(const ini_config *cfg, const char *name) {
|
||||
/* 按名加载公共实现。strict_deps=1:depends 校验强制(DKM-E44)——供
|
||||
* kern.dkm.load_by_name(万物互联 P3)等常规路径使用;
|
||||
* strict_deps=0:顺序豁免版——唯一调用方是 kernel/main.c VMM 路径的
|
||||
* pci+ahci 预加载(必须先于 apic/stage0,否则 guest 陷入 IDTR=0
|
||||
* VM-exit 风暴,见 main.c 注释)。设计内顺序豁免,登记于设计文档 §6。 */
|
||||
static void dsm_load_named_impl(const ini_config *cfg, const char *name, int strict_deps) {
|
||||
if (!name || dsm_ensure_manifest() != 0) {
|
||||
/* 严格错误策略插桩:按名加载 manifest 缺失零降级(DKM-E11) */
|
||||
panic_full("DKM-E11 NAMED LOAD MANIFEST MISSING",
|
||||
@@ -442,6 +610,14 @@ void dsm_load_named(const ini_config *cfg, const char *name) {
|
||||
log_info(drv->name);
|
||||
return;
|
||||
}
|
||||
/* P0:按名加载同样强制依赖(此时无同 stage 重试机会,miss 即判罚) */
|
||||
if (strict_deps && !dsm_deps_satisfied(drv, 0)) {
|
||||
log_error("[DSM] named driver dependency not satisfied: ");
|
||||
log_info(drv->name);
|
||||
panic_full("DKM-E44 DEPENDENCY NOT SATISFIED",
|
||||
"dsm_load_named: depends token not provided by any loaded driver", 0);
|
||||
return;
|
||||
}
|
||||
drv->boot_module = dsm_find_boot_module(drv->path);
|
||||
if (!drv->boot_module) {
|
||||
log_warn("[DSM] named module not found");
|
||||
@@ -477,6 +653,11 @@ void dsm_load_named(const ini_config *cfg, const char *name) {
|
||||
return;
|
||||
}
|
||||
drv->loaded = 1;
|
||||
drv->resolved = 1;
|
||||
/* P0:按名加载成功同样登记 provides */
|
||||
dsm_register_provides(drv);
|
||||
/* P1:stage>=4 provides 总线契约校验(DKM-E45) */
|
||||
dsm_verify_provides(stage, drv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -487,6 +668,14 @@ void dsm_load_named(const ini_config *cfg, const char *name) {
|
||||
"dsm_load_named: named driver not found in manifest", 0);
|
||||
}
|
||||
|
||||
void dsm_load_named(const ini_config *cfg, const char *name) {
|
||||
dsm_load_named_impl(cfg, name, 1);
|
||||
}
|
||||
|
||||
void dsm_load_named_boot(const ini_config *cfg, const char *name) {
|
||||
dsm_load_named_impl(cfg, name, 0);
|
||||
}
|
||||
|
||||
void dsm_load_by_manifest_ex(const ini_config *cfg) {
|
||||
dsm_load_stage_range(cfg, 0, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user