2026-07-02 15:40:39 +08:00
|
|
|
|
#include <utsm/log.h>
|
2026-10-03 00:30:54 +08:00
|
|
|
|
#include <utsm/panic.h>
|
2026-07-02 15:40:39 +08:00
|
|
|
|
#include <utsm/arena.h>
|
|
|
|
|
|
#include <utsm/utsm.h>
|
|
|
|
|
|
#include <utsm/drr.h>
|
2026-10-01 23:13:42 +08:00
|
|
|
|
#include <utsm/sched_ext.h>
|
2026-07-02 15:40:39 +08:00
|
|
|
|
#include <utsm/dkm.h>
|
|
|
|
|
|
#include <utsm/idt.h>
|
|
|
|
|
|
#include <utsm/dsk.h>
|
|
|
|
|
|
#include <utsm/block.h>
|
|
|
|
|
|
#include <utsm/net.h>
|
2026-07-28 12:00:02 +08:00
|
|
|
|
#include <utsm/ipc_shm.h>
|
2026-07-28 14:35:14 +08:00
|
|
|
|
#include <utsm/linux_compat.h>
|
2026-08-09 22:14:01 +08:00
|
|
|
|
#include <utsm/xj380_loader.h>
|
2026-07-31 13:53:49 +08:00
|
|
|
|
#include <utsm/instr.h>
|
2026-10-04 21:34:50 +08:00
|
|
|
|
#include <utsm/attest.h>
|
2026-07-31 13:53:49 +08:00
|
|
|
|
#include "ini_parser.h"
|
|
|
|
|
|
#include "../arch/x86_64/limine.h"
|
2026-08-09 22:14:01 +08:00
|
|
|
|
#include "../pe/pe_dll_manager.h"
|
2026-07-02 15:40:39 +08:00
|
|
|
|
|
|
|
|
|
|
void arch_halt_forever(void);
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
extern volatile struct limine_module_request g_module_request;
|
|
|
|
|
|
|
|
|
|
|
|
/* dkm/manifest.c: 带 FUCK [drivers] 过滤的 manifest 加载入口 */
|
|
|
|
|
|
void dsm_load_by_manifest_ex(const ini_config *cfg);
|
2026-10-01 23:13:42 +08:00
|
|
|
|
void dsm_load_named(const ini_config *cfg, const char *name);
|
2026-10-12 23:57:19 +08:00
|
|
|
|
/* P0 顺序豁免版:唯一调用方就是下方 VMM 路径(pci+ahci 必须先于 apic) */
|
|
|
|
|
|
void dsm_load_named_boot(const ini_config *cfg, const char *name);
|
2026-07-31 13:53:49 +08:00
|
|
|
|
|
2026-08-09 22:14:01 +08:00
|
|
|
|
/* dsk_loader.c: 按路径读取 FAT32 文件到 g_dsk_fat32_filedata 静态缓冲。
|
|
|
|
|
|
* Phase 1 已支持 LFN 长文件名 + 子目录遍历。 */
|
|
|
|
|
|
extern int fat32_read_path(const char *path, u8 **out_data, u32 *out_size);
|
|
|
|
|
|
|
2026-08-29 18:47:54 +08:00
|
|
|
|
/* dsk_loader.c: 实机启动日志落盘。把日志缓冲写入 FAT32 文件:
|
|
|
|
|
|
* SYSTEM/DESHAB64/DEV/BOOTLOG.TXT(DEV 缺失时回退根目录 BOOTLOG.TXT)。 */
|
|
|
|
|
|
extern int utsm_bootlog_write(const u8 *data, u32 size);
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
/* ---- 运行期配置全局变量(从 FUCK 文件初始化) ---- */
|
|
|
|
|
|
u32 g_utsm_max_segments = UTSM_MAX_SEGMENTS_DEFAULT;
|
|
|
|
|
|
u32 g_utsm_max_capabilities = UTSM_MAX_CAPABILITIES_DEFAULT;
|
|
|
|
|
|
u32 g_utsm_max_pckc_keys = UTSM_MAX_PCKC_KEYS_DEFAULT;
|
|
|
|
|
|
u64 g_utsm_arena_size = UTSM_ARENA_SIZE_DEFAULT;
|
|
|
|
|
|
u64 g_utsm_dirty_shard_pages = UTSM_DIRTY_SHARD_PAGES_DEFAULT;
|
|
|
|
|
|
|
2026-08-09 22:14:01 +08:00
|
|
|
|
/* ---- 兼容层配置全局变量([compat] 段,在所有使用它们的函数前定义) ---- */
|
|
|
|
|
|
char g_compat_lib_path[32] = "lib"; /* FAT32 根目录下的库子目录名 */
|
|
|
|
|
|
char g_compat_linux_guest_path[64] = "/usr/lib/deshab"; /* Linux guest 内库目录路径 */
|
|
|
|
|
|
int g_compat_linux_lib_sync = 1; /* 启动时推送 .so 到 Linux guest */
|
|
|
|
|
|
int g_compat_pe_dll_search = 1; /* PE 加载时从 FAT32 lib 搜索真实 DLL */
|
|
|
|
|
|
int g_compat_vscode_install = 1; /* 启动时安装 VSCode tarball 到 guest /opt */
|
2026-10-01 23:13:42 +08:00
|
|
|
|
int g_sched_enabled_cfg = 1; /* FUCK [sched] enable */
|
2026-08-09 22:14:01 +08:00
|
|
|
|
|
|
|
|
|
|
/* 将 FUCK [compat] 区的配置应用到兼容层全局变量。
|
|
|
|
|
|
* 必须在 utsm_apply_config 之后调用。 */
|
2026-10-12 23:57:19 +08:00
|
|
|
|
/* FUCK [panic] mode=strict|fallback(默认 strict)。其余取值按 strict 处理。 */
|
|
|
|
|
|
static void utsm_apply_panic_config(const ini_config *cfg) {
|
|
|
|
|
|
const char *mode = ini_get(cfg, "panic", "mode");
|
|
|
|
|
|
const char *want = "fallback";
|
|
|
|
|
|
int fallback = mode ? 1 : 0;
|
|
|
|
|
|
for (int i = 0; fallback && (mode[i] || want[i]); i++) {
|
|
|
|
|
|
if (mode[i] != want[i]) fallback = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
panic_set_fallback(fallback);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-09 22:14:01 +08:00
|
|
|
|
static void utsm_apply_compat_config(const ini_config *cfg) {
|
|
|
|
|
|
if (!cfg) return;
|
|
|
|
|
|
const char *lib_path = ini_get(cfg, "compat", "lib_path");
|
|
|
|
|
|
if (lib_path && lib_path[0]) {
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
while (lib_path[i] && i + 1 < (int)sizeof(g_compat_lib_path)) {
|
|
|
|
|
|
g_compat_lib_path[i] = lib_path[i];
|
|
|
|
|
|
i++;
|
|
|
|
|
|
}
|
|
|
|
|
|
g_compat_lib_path[i] = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
const char *guest_path = ini_get(cfg, "compat", "linux_lib_guest_path");
|
|
|
|
|
|
if (guest_path && guest_path[0]) {
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
while (guest_path[i] && i + 1 < (int)sizeof(g_compat_linux_guest_path)) {
|
|
|
|
|
|
g_compat_linux_guest_path[i] = guest_path[i];
|
|
|
|
|
|
i++;
|
|
|
|
|
|
}
|
|
|
|
|
|
g_compat_linux_guest_path[i] = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
g_compat_linux_lib_sync = ini_get_bool(cfg, "compat", "linux_lib_sync", 1);
|
|
|
|
|
|
g_compat_pe_dll_search = ini_get_bool(cfg, "compat", "pe_dll_search", 1);
|
|
|
|
|
|
g_compat_vscode_install = ini_get_bool(cfg, "compat", "vscode_install", 1);
|
|
|
|
|
|
|
|
|
|
|
|
log_info("[UTSM] compat config applied");
|
|
|
|
|
|
log_info("[UTSM] lib_path=");
|
|
|
|
|
|
log_info(g_compat_lib_path);
|
|
|
|
|
|
log_info("[UTSM] linux_guest_path=");
|
|
|
|
|
|
log_info(g_compat_linux_guest_path);
|
|
|
|
|
|
log_hex64("[UTSM] linux_lib_sync=", (u64)g_compat_linux_lib_sync);
|
|
|
|
|
|
log_hex64("[UTSM] pe_dll_search=", (u64)g_compat_pe_dll_search);
|
|
|
|
|
|
log_hex64("[UTSM] vscode_install=", (u64)g_compat_vscode_install);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* DLL 文件读取回调:从 FAT32 根目录下 lib/ 子目录读取 DLL。
|
|
|
|
|
|
* 路径构造成 "<g_compat_lib_path>/<name>"(lib 在 FAT32 根,不是 SYSTEM/lib!)。 */
|
|
|
|
|
|
static int dll_reader_from_fat32(const char *name, u8 **out_data, u32 *out_size) {
|
|
|
|
|
|
if (!name || !out_data || !out_size) return -1;
|
|
|
|
|
|
char path[128];
|
|
|
|
|
|
int pl = 0;
|
|
|
|
|
|
/* 拼接 g_compat_lib_path */
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
while (g_compat_lib_path[i] && pl + 1 < (int)sizeof(path)) {
|
|
|
|
|
|
path[pl++] = g_compat_lib_path[i++];
|
|
|
|
|
|
}
|
|
|
|
|
|
if (pl + 1 >= (int)sizeof(path)) return -1;
|
|
|
|
|
|
path[pl++] = '/';
|
|
|
|
|
|
/* 拼接 name */
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
while (name[i] && pl + 1 < (int)sizeof(path)) {
|
|
|
|
|
|
path[pl++] = name[i++];
|
|
|
|
|
|
}
|
|
|
|
|
|
path[pl] = 0;
|
|
|
|
|
|
return fat32_read_path(path, out_data, out_size);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
/* 将 FUCK [utsm] 区的配置应用到运行期全局变量 */
|
|
|
|
|
|
static void utsm_apply_config(const ini_config *cfg) {
|
|
|
|
|
|
if (!cfg) return;
|
|
|
|
|
|
g_utsm_max_segments = (u32)ini_get_int(cfg, "utsm", "max_segments", UTSM_MAX_SEGMENTS_DEFAULT);
|
|
|
|
|
|
g_utsm_max_capabilities = (u32)ini_get_int(cfg, "utsm", "max_capabilities", UTSM_MAX_CAPABILITIES_DEFAULT);
|
|
|
|
|
|
g_utsm_max_pckc_keys = (u32)ini_get_int(cfg, "utsm", "max_pckc_keys", UTSM_MAX_PCKC_KEYS_DEFAULT);
|
|
|
|
|
|
g_utsm_arena_size = (u64)ini_get_int(cfg, "utsm", "arena_size_mb", 16) * 1024 * 1024;
|
|
|
|
|
|
g_utsm_dirty_shard_pages = (u64)ini_get_int(cfg, "utsm", "dirty_shard_pages", UTSM_DIRTY_SHARD_PAGES_DEFAULT);
|
|
|
|
|
|
|
|
|
|
|
|
log_info("[UTSM] FUCK config applied");
|
|
|
|
|
|
log_hex64("[UTSM] max_segments=", g_utsm_max_segments);
|
|
|
|
|
|
log_hex64("[UTSM] max_pckc_keys=", g_utsm_max_pckc_keys);
|
|
|
|
|
|
log_hex64("[UTSM] dirty_shard_pages=", g_utsm_dirty_shard_pages);
|
2026-08-09 22:14:01 +08:00
|
|
|
|
|
|
|
|
|
|
/* 兼容层配置([compat] 段)— 复用同一 cfg 对象 */
|
|
|
|
|
|
utsm_apply_compat_config(cfg);
|
2026-07-31 13:53:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---- 全局启动配置(从 FUCK 文件读取) ---- */
|
|
|
|
|
|
static ini_config g_boot_cfg;
|
|
|
|
|
|
static int g_boot_cfg_loaded = 0;
|
2026-10-12 23:57:19 +08:00
|
|
|
|
|
|
|
|
|
|
/* D6 万物互联:FUCK 启动配置只读访问(kern.config.get 总线服务后端,
|
|
|
|
|
|
* bus.c 经前向声明调用;未加载时返回 NULL,消费方自行处理缺席)。 */
|
|
|
|
|
|
const ini_config *utsm_boot_cfg_get(void) {
|
|
|
|
|
|
return g_boot_cfg_loaded ? &g_boot_cfg : 0;
|
|
|
|
|
|
}
|
2026-10-04 21:34:50 +08:00
|
|
|
|
static int g_vmm_init_ok = 0; /* attest: vmm_vmx 能力打点 */
|
2026-07-31 13:53:49 +08:00
|
|
|
|
|
|
|
|
|
|
/* 从 Limine boot module 读取 FUCK 配置。
|
|
|
|
|
|
* cmdline="fuck:config" 的模块即为 FUCK 配置文件。
|
|
|
|
|
|
* 返回 0 成功,负数失败。 */
|
|
|
|
|
|
static int utsm_load_fuck_config(ini_config *cfg) {
|
|
|
|
|
|
struct limine_module_response *rsp = g_module_request.response;
|
|
|
|
|
|
if (!rsp) return -1;
|
|
|
|
|
|
for (u64 i = 0; i < rsp->module_count; i++) {
|
|
|
|
|
|
struct limine_file *f = rsp->modules[i];
|
|
|
|
|
|
if (f && f->cmdline) {
|
|
|
|
|
|
/* 比较 cmdline 是否为 "fuck:config" */
|
|
|
|
|
|
const char *c = f->cmdline;
|
|
|
|
|
|
const char *tag = "fuck:config";
|
|
|
|
|
|
int match = 1;
|
|
|
|
|
|
for (int j = 0; tag[j]; j++) {
|
|
|
|
|
|
if (c[j] != tag[j]) { match = 0; break; }
|
|
|
|
|
|
}
|
|
|
|
|
|
if (match && c[11] == 0) {
|
|
|
|
|
|
int rc = ini_parse((const char *)f->address, (u32)f->size, cfg);
|
|
|
|
|
|
if (rc == 0) {
|
|
|
|
|
|
log_info("[UTSM] FUCK config loaded from boot module");
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
log_warn("[UTSM] FUCK boot module not found");
|
|
|
|
|
|
return -2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-29 18:47:54 +08:00
|
|
|
|
/* === 实机日志持久化:把内存日志缓冲区写入 FAT32 文件 ===
|
|
|
|
|
|
* 目标: SYSTEM/DESHAB64/DEV/BOOTLOG.TXT(DEV 目录不存在时回退根目录 BOOTLOG.TXT)。
|
|
|
|
|
|
* 由 FUCK [boot] disk_log=1 启用。
|
|
|
|
|
|
* 相比旧原始扇区方案(LBA 2-1000):
|
|
|
|
|
|
* - 不再覆盖 GPT header/entries,不破坏 Limine 引导链
|
|
|
|
|
|
* - 日志以普通 FAT32 文件呈现,主机直接读取即可,无需 WinHex/dd
|
|
|
|
|
|
* 日志超出 BOOTLOG_MAX_BYTES 时截断(128KB 足够覆盖完整启动链)。 */
|
|
|
|
|
|
#define BOOTLOG_MAX_BYTES (128u * 1024u)
|
|
|
|
|
|
|
|
|
|
|
|
static void disk_log_flush(void) {
|
2026-08-09 22:14:01 +08:00
|
|
|
|
const dkm_kernel_api *api = dkm_get_kernel_api();
|
|
|
|
|
|
if (!api || !api->block || !api->block->write || !api->block->device_count) {
|
|
|
|
|
|
log_warn("[UTSM] disk_log: block device unavailable, skip");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (api->block->device_count() == 0) {
|
|
|
|
|
|
log_warn("[UTSM] disk_log: no block device, skip");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char *buf = log_get_buffer();
|
|
|
|
|
|
u32 len = log_get_length();
|
|
|
|
|
|
if (len == 0) {
|
|
|
|
|
|
log_warn("[UTSM] disk_log: log buffer empty, skip");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-08-29 18:47:54 +08:00
|
|
|
|
if (len > BOOTLOG_MAX_BYTES) len = BOOTLOG_MAX_BYTES;
|
2026-08-09 22:14:01 +08:00
|
|
|
|
|
2026-08-29 18:47:54 +08:00
|
|
|
|
int rc = utsm_bootlog_write((const u8 *)buf, len);
|
|
|
|
|
|
if (rc == 0) {
|
|
|
|
|
|
log_info("[UTSM] disk_log: BOOTLOG.TXT written");
|
|
|
|
|
|
log_hex64("[UTSM] disk_log: bytes=", len);
|
|
|
|
|
|
} else {
|
2026-10-03 21:26:04 +08:00
|
|
|
|
/* 【插桩白名单】设计内只读块路径:AHCI provider 当前仅注册最小
|
|
|
|
|
|
* read(CLAUDE.md ahci 驱动说明),write 恒为空,bootlog 落盘
|
|
|
|
|
|
* 失败属环境能力缺失而非数据读写错误。诊断日志不得阻断启动。 */
|
|
|
|
|
|
log_error("[UTSM] disk_log: FAT32 write failed (read-only block path, skip)");
|
2026-08-29 18:47:54 +08:00
|
|
|
|
log_hex64("[UTSM] disk_log: rc=", (u64)(i64)rc);
|
2026-08-09 22:14:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-02 15:40:39 +08:00
|
|
|
|
void kernel_main(void) {
|
2026-07-31 13:53:49 +08:00
|
|
|
|
/* ---- 插桩: 启动总时间戳 ---- */
|
|
|
|
|
|
INSTR_TS_DECL(boot_total);
|
|
|
|
|
|
INSTR_TS_BEGIN(boot_total);
|
|
|
|
|
|
|
2026-07-02 15:40:39 +08:00
|
|
|
|
serial_init();
|
|
|
|
|
|
log_info("[UTSM] boot");
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
/* ==== 真机硬件特征早期检测 (在任何初始化之前) ====
|
|
|
|
|
|
* 检测项目:
|
|
|
|
|
|
* 1. CPU vendor (GenuineIntel / AuthenticAMD / etc.)
|
|
|
|
|
|
* 2. 最大物理地址宽度 (CPUID.80000008H:EAX[7:0])
|
|
|
|
|
|
* 3. LA57 (5-level paging) 是否激活 → 拒绝启动
|
|
|
|
|
|
* 4. CPU 核心数 (CPUID.0BH 或 CPUID.01H)
|
|
|
|
|
|
* 5. PCIe MCFG 可用性 (后续由 ACPI 驱动检测)
|
|
|
|
|
|
*
|
|
|
|
|
|
* **QEMU 无法测试但真机必需的代码路径**:
|
|
|
|
|
|
* - LA57 拒绝: QEMU 默认不启用 5 级分页
|
|
|
|
|
|
* - 物理地址宽度 > 48: 只有大内存真机才有
|
|
|
|
|
|
* - AMD CPU vendor: QEMU 默认 Intel, 实机可能是 AMD
|
|
|
|
|
|
* - 多核: QEMU -smp 可以模拟, 但真机拓扑更复杂
|
|
|
|
|
|
*/
|
|
|
|
|
|
{
|
|
|
|
|
|
/* CPU vendor */
|
|
|
|
|
|
u32 a, b, c, d;
|
|
|
|
|
|
__asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(0), "c"(0));
|
|
|
|
|
|
char vendor[13];
|
|
|
|
|
|
vendor[0] = (char)(b & 0xff);
|
|
|
|
|
|
vendor[1] = (char)((b >> 8) & 0xff);
|
|
|
|
|
|
vendor[2] = (char)((b >> 16) & 0xff);
|
|
|
|
|
|
vendor[3] = (char)((b >> 24) & 0xff);
|
|
|
|
|
|
vendor[4] = (char)(d & 0xff);
|
|
|
|
|
|
vendor[5] = (char)((d >> 8) & 0xff);
|
|
|
|
|
|
vendor[6] = (char)((d >> 16) & 0xff);
|
|
|
|
|
|
vendor[7] = (char)((d >> 24) & 0xff);
|
|
|
|
|
|
vendor[8] = (char)(c & 0xff);
|
|
|
|
|
|
vendor[9] = (char)((c >> 8) & 0xff);
|
|
|
|
|
|
vendor[10] = (char)((c >> 16) & 0xff);
|
|
|
|
|
|
vendor[11] = (char)((c >> 24) & 0xff);
|
|
|
|
|
|
vendor[12] = 0;
|
|
|
|
|
|
log_info("[UTSM] CPU vendor: ");
|
|
|
|
|
|
log_info(vendor);
|
|
|
|
|
|
|
|
|
|
|
|
/* Max physical address width */
|
|
|
|
|
|
__asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(0x80000000), "c"(0));
|
|
|
|
|
|
if (a >= 0x80000008) {
|
|
|
|
|
|
__asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(0x80000008), "c"(0));
|
|
|
|
|
|
u32 phys_bits = a & 0xff;
|
|
|
|
|
|
u32 virt_bits = (a >> 8) & 0xff;
|
|
|
|
|
|
log_hex64("[UTSM] MaxPhysAddr bits=", phys_bits);
|
|
|
|
|
|
log_hex64("[UTSM] MaxVirtAddr bits=", virt_bits);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* LA57 early detection — 在 CR4 读之前先通过 CPUID 检查是否支持 */
|
|
|
|
|
|
__asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(7), "c"(0));
|
|
|
|
|
|
if (c & (1u << 16)) {
|
|
|
|
|
|
log_warn("[UTSM] CPU supports LA57 (5-level paging)");
|
|
|
|
|
|
/* 检查 CR4 是否实际启用了 LA57 */
|
|
|
|
|
|
u64 cr4;
|
|
|
|
|
|
__asm__ volatile("mov %%cr4, %0" : "=r"(cr4));
|
|
|
|
|
|
if (cr4 & (1ULL << 12)) {
|
|
|
|
|
|
log_error("[UTSM] LA57 is ACTIVE — this kernel requires 4-level paging");
|
|
|
|
|
|
log_error("[UTSM] Refusing to boot. Disable LA57 in firmware settings.");
|
2026-10-12 23:57:19 +08:00
|
|
|
|
/* 无备用路径:paging.c/mmio.c 的 4 级 walk 会写坏 5 级页表 */
|
|
|
|
|
|
panic_halt("VMM-E11 LA57 ACTIVE REFUSE BOOT",
|
2026-10-03 21:26:04 +08:00
|
|
|
|
"5-level paging active; kernel requires 4-level paging", 0);
|
2026-07-31 13:53:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* CPU core count — CPUID leaf 0BH (Intel Extended Topology) */
|
|
|
|
|
|
__asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(0), "c"(0));
|
|
|
|
|
|
if (a >= 0x0B) {
|
|
|
|
|
|
/* 尝试 level 0 获取 SMT 核心数 */
|
|
|
|
|
|
u32 level_type = 0, cores = 0;
|
|
|
|
|
|
__asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(0x0B), "c"(0));
|
|
|
|
|
|
level_type = (c >> 8) & 0xff;
|
|
|
|
|
|
cores = b & 0xffff;
|
|
|
|
|
|
if (level_type == 1 && cores > 0) {
|
|
|
|
|
|
log_hex64("[UTSM] SMT threads=", cores);
|
|
|
|
|
|
}
|
|
|
|
|
|
__asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(0x0B), "c"(1));
|
|
|
|
|
|
level_type = (c >> 8) & 0xff;
|
|
|
|
|
|
cores = b & 0xffff;
|
|
|
|
|
|
if (level_type == 2 && cores > 0) {
|
|
|
|
|
|
log_hex64("[UTSM] logical processors=", cores);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
/* fallback: CPUID.01H EBX[23:16] */
|
|
|
|
|
|
__asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(1), "c"(0));
|
|
|
|
|
|
u32 lc = (b >> 16) & 0xff;
|
|
|
|
|
|
log_hex64("[UTSM] logical processors (legacy)=", lc);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---- 插桩: CPU 检测完成,记录 vendor ---- */
|
|
|
|
|
|
INSTR_PROBE(BOOT, (u64)vendor[0] | ((u64)vendor[1] << 8), 0, 0, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---- 插桩: IDT 初始化耗时 ---- */
|
|
|
|
|
|
INSTR_TS_DECL(ts_idt);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_idt);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
idt_init();
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_END(ts_idt, "idt_init");
|
|
|
|
|
|
|
|
|
|
|
|
/* === 读取 FUCK 配置(通过 Limine boot module 预加载) === */
|
|
|
|
|
|
g_boot_cfg_loaded = (utsm_load_fuck_config(&g_boot_cfg) == 0);
|
|
|
|
|
|
ini_config *cfg = g_boot_cfg_loaded ? &g_boot_cfg : NULL;
|
|
|
|
|
|
|
2026-10-02 19:48:54 +08:00
|
|
|
|
/* D4: DKM 彩色日志总开关(FUCK [debug] color_log,默认开;
|
|
|
|
|
|
* 颜色只走串口,BOOTLOG.TXT 保持纯文本) */
|
|
|
|
|
|
log_color_enable(ini_get_bool(cfg, "debug", "color_log", 1));
|
|
|
|
|
|
|
2026-10-12 23:57:19 +08:00
|
|
|
|
utsm_apply_panic_config(cfg);
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
/* ---- 插桩: FUCK 配置加载完成 ---- */
|
|
|
|
|
|
INSTR_PROBE(BOOT, (u64)g_boot_cfg_loaded, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
/* === 初始化插桩系统(在 arena_init 之前,但需要 FUCK 配置) === */
|
|
|
|
|
|
/* 注意: probe_init 需要 arena,所以 instr_init 必须在 arena_init 之后。
|
|
|
|
|
|
* 此处先设置 g_instr_enabled 等全局变量,probe_init 延后到 arena 后。
|
|
|
|
|
|
* 实际上 instr_init 内部会调用 probe_init,而 probe_init 需要 kmem_alloc。
|
|
|
|
|
|
* 所以我们将 instr_init 移到 arena_init 之后。*/
|
|
|
|
|
|
|
|
|
|
|
|
/* === 应用 UTSM 算法参数到运行期全局变量 === */
|
|
|
|
|
|
utsm_apply_config(cfg);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
|
|
|
|
|
|
log_info("[UTSM] arena init begin");
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_DECL(ts_arena);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_arena);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
arena_init();
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_END(ts_arena, "arena_init");
|
2026-07-02 15:40:39 +08:00
|
|
|
|
log_info("[UTSM] arena init ok");
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
/* ---- 插桩: arena 就绪后初始化插桩系统(含探测缓冲分配) ---- */
|
|
|
|
|
|
instr_init(cfg);
|
|
|
|
|
|
|
2026-07-02 15:40:39 +08:00
|
|
|
|
log_info("[UTSM] dma init begin");
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_DECL(ts_dma);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_dma);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
dma_init();
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_END(ts_dma, "dma_init");
|
2026-07-02 15:40:39 +08:00
|
|
|
|
log_info("[UTSM] dma init ok");
|
|
|
|
|
|
|
|
|
|
|
|
log_info("[UTSM] net registry init begin");
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_DECL(ts_net);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_net);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
net_init();
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_END(ts_net, "net_init");
|
2026-07-02 15:40:39 +08:00
|
|
|
|
log_info("[UTSM] net registry init ok");
|
|
|
|
|
|
|
2026-07-03 21:13:04 +08:00
|
|
|
|
log_info("[UTSM] drr init begin");
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_DECL(ts_drr);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_drr);
|
2026-10-02 14:34:35 +08:00
|
|
|
|
/* R3b: FUCK [utsm] drr_emergency_pool_kb / drr_recovery_log_size 接线 */
|
|
|
|
|
|
drr_apply_config((u64)ini_get_int(cfg, "utsm", "drr_emergency_pool_kb", 0),
|
|
|
|
|
|
(u64)ini_get_int(cfg, "utsm", "drr_recovery_log_size", 0));
|
2026-07-03 21:13:04 +08:00
|
|
|
|
drr_init();
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_END(ts_drr, "drr_init");
|
2026-07-03 21:13:04 +08:00
|
|
|
|
log_info("[UTSM] drr init ok");
|
2026-10-04 21:34:50 +08:00
|
|
|
|
/* 启动期能力证明:DRR 快照/回滚已立;真 MAC 为 Phase 9(占位 CRC64) */
|
|
|
|
|
|
attest_report_ready("drr", "DRR-E30");
|
|
|
|
|
|
attest_report("drr_real_mac", "DRR-E31", 0);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
|
|
|
|
|
|
log_info("[UTSM] core init begin");
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_DECL(ts_utsm);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_utsm);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
utsm_init();
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_END(ts_utsm, "utsm_init");
|
2026-07-02 15:40:39 +08:00
|
|
|
|
log_info("[UTSM] init ok");
|
2026-10-04 21:34:50 +08:00
|
|
|
|
/* 启动期能力证明:utsm_init 内含 PCKC 派生往返自证(失败即 PCKC-E01) */
|
|
|
|
|
|
attest_report_ready("pckc_derive", "PCKC-E02");
|
2026-07-02 15:40:39 +08:00
|
|
|
|
|
2026-10-03 15:40:00 +08:00
|
|
|
|
/* === 封缄内存极早期初始化(UTSM-E01..E04) ===
|
|
|
|
|
|
* .sealed 区为空 / root key 缺失 → 此处极早期 panic,绝不带病前进。 */
|
|
|
|
|
|
{
|
2026-10-12 23:57:19 +08:00
|
|
|
|
extern int utsm_sealed_early_init(void);
|
|
|
|
|
|
attest_report("sealed_mem", "UTSM-E05", utsm_sealed_early_init() == 0);
|
2026-10-03 15:40:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-10-01 23:13:42 +08:00
|
|
|
|
/* === SAS-R0-PCQ 调度器:bootstrap 任务绑定(Phase 7) ===
|
|
|
|
|
|
* 只做 sched_init + cpu_init + bootstrap TCB(绑定当前 rsp),
|
|
|
|
|
|
* 不开中断、不碰定时器,对既有启动行为零影响。
|
|
|
|
|
|
* 抢占在 selftest 之后、demo 窗口内才启用。 */
|
|
|
|
|
|
{
|
|
|
|
|
|
u32 s_tick_hz = (u32)ini_get_int(cfg, "sched", "tick_hz", 100);
|
|
|
|
|
|
u32 s_slice_ms = (u32)ini_get_int(cfg, "sched", "timeslice_ms", 10);
|
|
|
|
|
|
u32 s_demo_ms = (u32)ini_get_int(cfg, "sched", "demo_ms", 1000);
|
|
|
|
|
|
int s_demo_fault = ini_get_bool(cfg, "sched", "demo_fault", 0);
|
|
|
|
|
|
g_sched_enabled_cfg = ini_get_bool(cfg, "sched", "enable", 1);
|
|
|
|
|
|
utsm_sched_config(s_tick_hz, s_slice_ms, s_demo_ms, s_demo_fault);
|
|
|
|
|
|
log_hex64("[SCHED] cfg enable=", (u64)g_sched_enabled_cfg);
|
|
|
|
|
|
log_hex64("[SCHED] cfg demo_ms=", s_demo_ms);
|
|
|
|
|
|
if (utsm_sched_bootstrap_init() < 0) {
|
2026-10-03 15:49:19 +08:00
|
|
|
|
/* SAS-R0 特色自证:调度器 bootstrap 失败 = 单地址空间 O(1)
|
|
|
|
|
|
* 调度器没有真正立起来,零降级 panic(SAS-E01) */
|
|
|
|
|
|
panic_full("SAS-E01 SCHED BOOTSTRAP FAILED",
|
|
|
|
|
|
"SAS-R0-PCQ scheduler bootstrap failed (was: non-fatal)", 0);
|
2026-10-12 23:57:19 +08:00
|
|
|
|
/* fallback:不开 demo 窗口,sched 能力不报就绪 */
|
|
|
|
|
|
g_sched_enabled_cfg = 0;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
attest_report_ready("sched", "SAS-E02");
|
2026-10-01 23:13:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_DECL(ts_dkm);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_dkm);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
dkm_init();
|
|
|
|
|
|
dkm_fill_platform_info();
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_END(ts_dkm, "dkm_init");
|
|
|
|
|
|
|
2026-08-09 22:14:01 +08:00
|
|
|
|
/* === VMM — 可通过 FUCK [boot] vmm=0 跳过 ===
|
|
|
|
|
|
* P8.4: Moved BEFORE DKM driver loading so VMM self-test runs even if
|
|
|
|
|
|
* a stage2 driver (e.g. fat32) crashes under KVM nested VMX. */
|
2026-07-31 13:53:49 +08:00
|
|
|
|
int run_vmm = ini_get_bool(cfg, "boot", "vmm", 1);
|
2026-10-04 21:34:50 +08:00
|
|
|
|
g_vmm_init_ok = 0;
|
2026-07-31 13:53:49 +08:00
|
|
|
|
if (run_vmm && vmm_init() == 0) {
|
2026-10-04 21:34:50 +08:00
|
|
|
|
g_vmm_init_ok = 1;
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_DECL(ts_vmm);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_vmm);
|
|
|
|
|
|
log_info("[UTSM] VMM init ok");
|
|
|
|
|
|
int vmm_st = vmm_self_test();
|
2026-08-09 22:14:01 +08:00
|
|
|
|
/* P8.4: On KVM nested VMX, self-test VMCS may fail but Linux guest VMCS
|
|
|
|
|
|
* (configured separately) may still work. Force-continue regardless. */
|
|
|
|
|
|
if (vmm_st != 0) {
|
|
|
|
|
|
log_warn("[UTSM] VMM self-test FAIL, but continuing to Linux guest");
|
2026-10-03 21:26:04 +08:00
|
|
|
|
panic_full("VMM-E12 VMM SELFTEST FAIL",
|
|
|
|
|
|
"VMM self-test failed; force-continue removed by instrumentation", 0);
|
2026-08-09 22:14:01 +08:00
|
|
|
|
vmm_st = 0; /* force pass to continue to Linux guest */
|
|
|
|
|
|
}
|
2026-07-31 13:53:49 +08:00
|
|
|
|
if (vmm_st == 0) {
|
|
|
|
|
|
INSTR_TS_END(ts_vmm, "vmm_init+selftest");
|
|
|
|
|
|
log_info("[UTSM] VMM self-test PASS");
|
|
|
|
|
|
|
2026-10-01 23:13:42 +08:00
|
|
|
|
/* Only pci+ahci before linux_launch. Loading apic/stage0 first
|
|
|
|
|
|
* left the guest in an IDTR=0 VM-exit storm. Remaining DKM
|
2026-10-12 23:57:19 +08:00
|
|
|
|
* still loads after the guest parks.
|
|
|
|
|
|
* P0 依赖图:此处用顺序豁免版(pci depends irq/apic 未加载),
|
|
|
|
|
|
* 豁免登记见 docs/RE/万物互联与服务总线设计.md §6。 */
|
|
|
|
|
|
dsm_load_named_boot(cfg, "pci");
|
|
|
|
|
|
dsm_load_named_boot(cfg, "ahci");
|
2026-10-01 23:13:42 +08:00
|
|
|
|
|
2026-10-03 15:40:00 +08:00
|
|
|
|
/* === Linux guest — 可通过 FUCK [boot] linux_guest=0 跳过 ===
|
|
|
|
|
|
* 严格错误策略:linux_guest=1 即"请求了 guest"——模块缺失、
|
|
|
|
|
|
* 启动失败、IPC 失败一律 panic(VMM-E/LNX-E),零降级。 */
|
2026-07-31 13:53:49 +08:00
|
|
|
|
int run_linux = ini_get_bool(cfg, "boot", "linux_guest", 1);
|
2026-10-12 23:57:19 +08:00
|
|
|
|
int linux_ready = run_linux;
|
|
|
|
|
|
if (run_linux && linux_loader_init() != 0) {
|
|
|
|
|
|
panic_full("VMM-E01 LINUX BZIMAGE MISSING",
|
|
|
|
|
|
"linux_guest=1 but bzImage boot module not found", 0);
|
|
|
|
|
|
linux_ready = 0; /* fallback:跳过 Linux guest */
|
|
|
|
|
|
}
|
|
|
|
|
|
if (linux_ready) {
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_DECL(ts_linux);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_linux);
|
|
|
|
|
|
log_info("[UTSM] Linux loader init ok");
|
|
|
|
|
|
|
2026-10-12 23:57:19 +08:00
|
|
|
|
int lin_st = -1;
|
|
|
|
|
|
int launched = 0;
|
2026-07-31 13:53:49 +08:00
|
|
|
|
if (ipc_shm_init() == 0) {
|
|
|
|
|
|
log_info("[UTSM] IPC shm init ok");
|
2026-10-12 23:57:19 +08:00
|
|
|
|
lin_st = linux_launch();
|
|
|
|
|
|
launched = 1;
|
2026-07-31 13:53:49 +08:00
|
|
|
|
} else {
|
2026-10-03 15:40:00 +08:00
|
|
|
|
panic_full("LNX-E03 IPC SHM INIT FAILED",
|
|
|
|
|
|
"IPC shared memory init failed (was: non-fatal)", 0);
|
2026-10-12 23:57:19 +08:00
|
|
|
|
log_warn("[UTSM] fallback: Linux guest launch skipped (no IPC)");
|
2026-07-31 13:53:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
INSTR_TS_END(ts_linux, "linux_launch");
|
|
|
|
|
|
if (lin_st == 0) {
|
|
|
|
|
|
log_info("[UTSM] Linux guest parked (daemon ready)");
|
|
|
|
|
|
linux_compat_init();
|
2026-08-09 22:14:01 +08:00
|
|
|
|
/* Phase 2: 启动时把 FAT32 lib 目录下 .so 全量推送到 Linux guest */
|
|
|
|
|
|
if (g_compat_linux_lib_sync) {
|
|
|
|
|
|
int lsrc = lxc_sync_lib_dir(g_compat_linux_guest_path);
|
|
|
|
|
|
if (lsrc == 0) log_info("[UTSM] lib sync ok");
|
2026-10-03 00:30:54 +08:00
|
|
|
|
else {
|
|
|
|
|
|
/* 严格错误策略插桩:lib 同步失败零降级(LNX-E01) */
|
|
|
|
|
|
panic_full("LNX-E01 LIB SYNC FAILED",
|
|
|
|
|
|
"FAT32 lib dir sync to Linux guest failed", 0);
|
|
|
|
|
|
}
|
2026-08-09 22:14:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
/* VSCode Phase 5: tarball module 存在时装到 guest /opt/vscode
|
2026-10-03 00:30:54 +08:00
|
|
|
|
* (已安装则秒跳过;失败零降级 panic) */
|
2026-08-09 22:14:01 +08:00
|
|
|
|
if (g_compat_vscode_install) {
|
|
|
|
|
|
int vsrc = lxc_vscode_install();
|
|
|
|
|
|
if (vsrc == 0) log_info("[UTSM] vscode ready");
|
2026-10-03 00:30:54 +08:00
|
|
|
|
else {
|
|
|
|
|
|
/* 严格错误策略插桩:VSCode 安装失败零降级(LNX-E02) */
|
|
|
|
|
|
panic_full("LNX-E02 VSCODE INSTALL FAILED",
|
|
|
|
|
|
"vscode tarball install into guest failed", 0);
|
|
|
|
|
|
}
|
2026-08-09 22:14:01 +08:00
|
|
|
|
}
|
2026-10-12 23:57:19 +08:00
|
|
|
|
} else if (launched) {
|
2026-10-03 15:40:00 +08:00
|
|
|
|
/* 严格错误策略插桩:guest 启动失败零降级(VMM-E02) */
|
2026-07-31 13:53:49 +08:00
|
|
|
|
log_error("[UTSM] Linux launch failed");
|
|
|
|
|
|
log_hex64("[UTSM] Linux st=", (u64)(i64)lin_st);
|
2026-10-03 15:40:00 +08:00
|
|
|
|
panic_full("VMM-E02 LINUX LAUNCH FAILED",
|
|
|
|
|
|
"linux_guest=1 requested but VMX launch failed", 0);
|
2026-07-28 12:00:02 +08:00
|
|
|
|
}
|
2026-10-12 23:57:19 +08:00
|
|
|
|
} else if (!run_linux) {
|
2026-10-03 15:40:00 +08:00
|
|
|
|
log_warn("[UTSM] Linux guest disabled by FUCK (linux_guest=0)");
|
2026-07-28 12:00:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2026-07-31 13:53:49 +08:00
|
|
|
|
INSTR_TS_END(ts_vmm, "vmm_init+selftest");
|
|
|
|
|
|
log_error("[UTSM] VMM self-test FAIL");
|
|
|
|
|
|
log_hex64("[UTSM] VMM st=", (u64)(i64)vmm_st);
|
2026-10-03 21:26:04 +08:00
|
|
|
|
panic_full("VMM-E13 VMM SELFTEST FAIL",
|
|
|
|
|
|
"VMM self-test failed (non-zero status)", 0);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
}
|
2026-08-09 22:14:01 +08:00
|
|
|
|
|
|
|
|
|
|
/* === OpenXJ380 guest — 可通过 FUCK [boot] xj380_guest=0 跳过 ===
|
|
|
|
|
|
* 三内核架构路线 B:XJ380 作为第二 guest(与 Linux 并列)。
|
2026-10-03 15:40:00 +08:00
|
|
|
|
* 严格错误策略:xj380_guest=1 即"请求了 guest"——模块缺失或
|
|
|
|
|
|
* 启动失败一律 panic(VMM-E03/E04),零降级。 */
|
2026-08-09 22:14:01 +08:00
|
|
|
|
int run_xj380 = ini_get_bool(cfg, "boot", "xj380_guest", 1);
|
2026-10-12 23:57:19 +08:00
|
|
|
|
if (run_xj380 && xj380_loader_init() != 0) {
|
|
|
|
|
|
panic_full("VMM-E03 XJ380 KERNEL.KRL MISSING",
|
|
|
|
|
|
"xj380_guest=1 but kernel.krl boot module not found", 0);
|
|
|
|
|
|
log_warn("[UTSM] fallback: XJ380 guest skipped");
|
|
|
|
|
|
} else if (run_xj380) {
|
2026-08-09 22:14:01 +08:00
|
|
|
|
INSTR_TS_DECL(ts_xj380);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_xj380);
|
|
|
|
|
|
log_info("[UTSM] XJ380 loader init ok");
|
|
|
|
|
|
int xj_st = xj380_launch();
|
|
|
|
|
|
INSTR_TS_END(ts_xj380, "xj380_launch");
|
|
|
|
|
|
if (xj_st == 0) {
|
|
|
|
|
|
log_info("[UTSM] XJ380 guest terminated (host resumed)");
|
|
|
|
|
|
} else {
|
2026-10-03 15:40:00 +08:00
|
|
|
|
/* 严格错误策略插桩:XJ380 启动失败零降级(VMM-E04) */
|
2026-08-09 22:14:01 +08:00
|
|
|
|
log_error("[UTSM] XJ380 launch failed");
|
|
|
|
|
|
log_hex64("[UTSM] XJ380 st=", (u64)(i64)xj_st);
|
2026-10-03 15:40:00 +08:00
|
|
|
|
panic_full("VMM-E04 XJ380 LAUNCH FAILED",
|
|
|
|
|
|
"xj380_guest=1 requested but launch failed", 0);
|
2026-08-09 22:14:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2026-10-03 15:40:00 +08:00
|
|
|
|
log_warn("[UTSM] XJ380 guest disabled by FUCK (xj380_guest=0)");
|
2026-08-09 22:14:01 +08:00
|
|
|
|
}
|
2026-07-02 15:40:39 +08:00
|
|
|
|
} else {
|
2026-07-31 13:53:49 +08:00
|
|
|
|
log_warn("[UTSM] VMM unavailable (VMX not supported or disabled by FUCK)");
|
|
|
|
|
|
}
|
2026-10-04 21:34:50 +08:00
|
|
|
|
/* 启动期能力证明:VMX 可用性(未就绪时是否 panic 由 FUCK [attest] require_vmm_vmx 决定) */
|
|
|
|
|
|
attest_report("vmm_vmx", "VMM-E30", run_vmm && g_vmm_init_ok);
|
2026-07-31 13:53:49 +08:00
|
|
|
|
|
2026-08-09 22:14:01 +08:00
|
|
|
|
/* === 驱动加载 — 按 [drivers] 区过滤 === */
|
|
|
|
|
|
INSTR_TS_DECL(ts_dsm);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_dsm);
|
|
|
|
|
|
dsm_load_by_manifest_ex(cfg);
|
|
|
|
|
|
INSTR_TS_END(ts_dsm, "dsm_load_manifest");
|
|
|
|
|
|
|
2026-10-04 21:34:50 +08:00
|
|
|
|
/* === 启动期能力证明:DKM 驱动派生能力 + 设计占位能力 === */
|
|
|
|
|
|
{
|
|
|
|
|
|
u32 net_total = 0, net_wlan = 0;
|
|
|
|
|
|
net_attest_counts(&net_total, &net_wlan);
|
|
|
|
|
|
attest_report("net_wired", "NET-E02", net_total > 0);
|
|
|
|
|
|
attest_report("net_wlan", "NET-E01", net_wlan > 0);
|
|
|
|
|
|
/* FAT32 读写:块 provider 需同时具备 read+write(AHCI WRITE DMA) */
|
|
|
|
|
|
{
|
|
|
|
|
|
const dkm_kernel_api *kapi = dkm_get_kernel_api();
|
|
|
|
|
|
int fat_rw = (kapi && kapi->block && kapi->block->read && kapi->block->write) ? 1 : 0;
|
|
|
|
|
|
attest_report("fs_fat32_rw", "FS-E10", fat_rw);
|
|
|
|
|
|
}
|
|
|
|
|
|
/* 设计已定但未实现的能力(占位,require 决定是否阻断启动) */
|
|
|
|
|
|
attest_report("fs_ext4_rw", "FS-E11", 1); /* FS-E 严格模式已落(DSK 侧读写闭环) */
|
|
|
|
|
|
attest_report("pkg", "PKG-E10", 0);
|
|
|
|
|
|
attest_report("brand_anim", "BRAND-E10", 0);
|
|
|
|
|
|
attest_report("dkm_hot_unload", "DKM-E60", 0);
|
2026-10-12 23:57:19 +08:00
|
|
|
|
/* D6 万物互联:dkm_bus 落地,按名服务导出能力翻绿
|
|
|
|
|
|
* (kapi 只读表 + bus 双向注册-消费)。 */
|
|
|
|
|
|
attest_report("dkm_api_export", "DKM-E61", 1);
|
2026-10-04 21:34:50 +08:00
|
|
|
|
attest_report("nvme_rw", "NVME-E30", 0);
|
|
|
|
|
|
attest_report("virtio_net", "VNET-E30", 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-10-01 23:29:49 +08:00
|
|
|
|
/* === F4: 分级启动自检 — FUCK [boot] selftest=0|1|2 ===
|
|
|
|
|
|
* 0=关 / 1=快速(结构健全性) / 2=全量(+DMA 探针 + UTSM selftest) */
|
|
|
|
|
|
{
|
|
|
|
|
|
int self_level = ini_get_int(cfg, "boot", "selftest", 1);
|
|
|
|
|
|
extern int boot_selftest_run(int level);
|
|
|
|
|
|
extern void boot_panic_test(const ini_config *cfg);
|
|
|
|
|
|
boot_selftest_run(self_level);
|
|
|
|
|
|
boot_panic_test(cfg);
|
|
|
|
|
|
if (self_level >= 2) {
|
|
|
|
|
|
INSTR_TS_DECL(ts_self);
|
|
|
|
|
|
INSTR_TS_BEGIN(ts_self);
|
|
|
|
|
|
int result = utsm_selftest_run();
|
|
|
|
|
|
INSTR_TS_END(ts_self, "selftest");
|
|
|
|
|
|
if (result == 0) {
|
|
|
|
|
|
log_info("[UTSM] SELFTEST PASS");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
log_error("[UTSM] SELFTEST FAIL");
|
2026-10-03 21:26:04 +08:00
|
|
|
|
panic_full("VMM-E14 SELFTEST FAIL",
|
|
|
|
|
|
"utsm_selftest_run returned non-zero", 0);
|
2026-10-01 23:29:49 +08:00
|
|
|
|
}
|
2026-08-09 22:14:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-10-01 23:13:42 +08:00
|
|
|
|
/* === SAS-R0-PCQ 调度器:demo 任务 + LAPIC tick 抢占启用(Phase 7) ===
|
|
|
|
|
|
* 此刻 DKM 全部驱动加载完毕(timer.drv 的 PIT 校准已完成且此后无人
|
|
|
|
|
|
* 再用 PIT)、VMM/Linux/XJ380 guest 已 park/terminate —— LAPIC timer
|
|
|
|
|
|
* 接管 tick 源。demo 窗口内 bootstrap 被周期抢占,demo 任务交错运行。 */
|
|
|
|
|
|
if (g_sched_enabled_cfg) {
|
|
|
|
|
|
utsm_sched_demo_window();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
/* ---- 插桩: DSK 加载跳转前记录 ---- */
|
|
|
|
|
|
INSTR_PROBE(DSK0, 0, 0, 0, 0);
|
|
|
|
|
|
|
2026-08-09 22:14:01 +08:00
|
|
|
|
/* Phase 3: 初始化 PE DLL 管理器(注册 FAT32 读取回调)。
|
|
|
|
|
|
* DSK 跳转前 block provider 已就绪,fat32_read_path 可用。 */
|
|
|
|
|
|
if (g_compat_pe_dll_search) {
|
|
|
|
|
|
pe_dll_manager_init(dll_reader_from_fat32);
|
|
|
|
|
|
log_info("[UTSM] PE DLL manager initialized (SYSTEM/lib)");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-29 18:47:54 +08:00
|
|
|
|
/* === 实机日志持久化:把启动日志写入 FAT32 文件 BOOTLOG.TXT === */
|
2026-08-09 22:14:01 +08:00
|
|
|
|
{
|
|
|
|
|
|
int disk_log = ini_get_bool(cfg, "boot", "disk_log", 0);
|
|
|
|
|
|
if (disk_log) {
|
2026-10-01 23:13:42 +08:00
|
|
|
|
disk_log_flush();
|
2026-08-09 22:14:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-10-04 21:34:50 +08:00
|
|
|
|
/* === SAS-R0 启动期能力证明:交接 DSK 前统一核查 ===
|
|
|
|
|
|
* FUCK [attest] require_<name>=1(默认)而能力未就绪 → 莲花屏 panic。 */
|
|
|
|
|
|
attest_check(cfg);
|
|
|
|
|
|
|
2026-10-01 23:13:42 +08:00
|
|
|
|
/* === 调度器静默(Phase 7/8 收尾) ===
|
|
|
|
|
|
* 停 LAPIC timer、注销 tick/异常 handler、杀 demo 任务——保证
|
|
|
|
|
|
* dsk_load_and_jump 的 DSK 交接路径与无调度器时逐字节一致。 */
|
|
|
|
|
|
utsm_sched_quiesce();
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
if (dsk_load_and_jump() != 0) {
|
|
|
|
|
|
log_error("[UTSM] DSK jump failed");
|
2026-10-12 23:57:19 +08:00
|
|
|
|
/* 启动链终点,无可继续的路径:两种模式都上莲花屏 */
|
|
|
|
|
|
panic_halt("VMM-E15 DSK JUMP FAILED",
|
2026-10-03 21:26:04 +08:00
|
|
|
|
"dsk_load_and_jump returned non-zero", 0);
|
2026-07-02 15:40:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-31 13:53:49 +08:00
|
|
|
|
/* ---- 插桩: 启动总耗时(仅在 DSK 跳转失败时可见) ---- */
|
|
|
|
|
|
INSTR_TS_END(boot_total, "boot_total");
|
|
|
|
|
|
|
2026-10-01 23:13:42 +08:00
|
|
|
|
arch_halt_forever();/*I LOVE YOU*/
|
2026-07-02 15:40:39 +08:00
|
|
|
|
}
|