Files

319 lines
11 KiB
C
Raw Permalink Normal View History

/* ===================================================================
* 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);
}