Files
Deshab-OS/CODE/UTSM/include/utsm/xj380_loader.h
T
2026-08-09 22:20:01 +08:00

107 lines
5.6 KiB
C
Raw 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.
#ifndef UTSM_XJ380_LOADER_H
#define UTSM_XJ380_LOADER_H
#include <utsm/types.h>
/* xj380_loader.h — OpenXJ380 (kernel.krl) guest loader for UTSM VMX non-root guest.
*
* 三内核架构路线 B:UTSM hypervisor 同时运行 Linux 与 OpenXJ380 两个 VM guest。
* 本模块把 OpenXJ380 编译产物 kernel.krl(固定链接 0xFFFFFFFF80000000 的
* ELF64 ET_EXEC)作为第二 guest 加载:
* - 解析 ELF PT_LOAD 段 → 装入 guest 物理内存
* - 构造 guest 初始页表(恒等 + HHDM + 内核区三区布局,同 XJ380 引导器契约)
* - 构造 BOOT_CONFIG / FrameBufferConfig / 伪 EFI_SYSTEM_TABLE 交接
* - 构造 MADT/FADT/HPET/MCFG 桩表(LAPIC/IOAPIC/HPET/MMCONF 均为幽灵地址)
* - 建立 EPT 映射(boot area / framebuffer / kernel / RAM)
*
* XJ380 内核侧启动契约(证据见 OpenXJ380/boot/include/boot.h 与
* OpenXJ380/kernel/main.cpp / memory/frame.cpp):
* - KernelMain(fbc, SystemTable, BootConfig) — 3 个 SysV 参数,引用退化为指针
* - BOOT_CONFIG 在入口立即被 memcpy 拷贝(main.cpp:281),原缓冲仅需入口可读
* - MemoryMap.Buffer / saved_mtrrs 是物理地址,内核自行 +0xffff800000000000
* - temp_stack[] 是 HHDM 虚拟地址数组(仅拷贝,1 CPU 时不 deref)
* - MADT 在清低半(main.cpp:392)之前按物理地址直读,之后经 HHDM 读
*
* 里程碑 M1:guest 启动至根文件系统挂载(预期在 mount_root 死循环处停止,
* 无虚拟块设备)。串口经 UTSM COM1 模拟可见 XJ380 启动全程。
*/
/* ===== XJ380 guest GPA 布局 =====
*
* 0x00000000-0x0000FFFF : 保留(XJ380 AP 跳板区 APU_BASE_ADDR=0x10000)
* 0x00020000-0x00033FFF : UTSM loader 私有 boot area(<1MB,内核不分配)
* page tables / GDT / ACPI 桩表 / 内存图 /
* BOOT_CONFIG / MTRR 缓冲 / stack / 伪 EFI 表
* 0x00100000-0x00400000 : framebuffer 1024x768x4(3MB,隐式保留)
* 0x01000000-0x02FFFFFF : kernel.krl 内核镜像窗口(32MB,隐式保留)
* 0x03000000-0x43000000 : guest RAM 1GB(内存图中唯一的 Conventional 区)
*/
#define XJ380_KERNEL_VADDR 0xFFFFFFFF80000000ULL /* XJ380 linker.ld 固定链接地址 */
#define XJ380_HHDM_OFFSET 0xFFFF800000000000ULL /* XJ380 HHDM 常量(hhdm.cpp:15) */
#define XJ380_BOOT_AREA_GPA 0x00020000ULL /* 128KB,避开 AP 跳板 0x10000 */
#define XJ380_PGT_GPA (XJ380_BOOT_AREA_GPA + 0x0000) /* 8 页: PML4/PDPT0/PD0-3/PDPT_K/PD_K */
#define XJ380_PGT_SIZE (8 * 4096)
#define XJ380_GDT_GPA (XJ380_PGT_GPA + XJ380_PGT_SIZE)
#define XJ380_MADT_GPA (XJ380_GDT_GPA + 0x1000)
#define XJ380_FADT_GPA (XJ380_MADT_GPA + 0x1000)
#define XJ380_MCFG_GPA (XJ380_FADT_GPA + 0x1000)
#define XJ380_HPET_GPA (XJ380_MCFG_GPA + 0x1000)
#define XJ380_MEMMAP_GPA (XJ380_HPET_GPA + 0x1000)
#define XJ380_BOOTCFG_GPA (XJ380_MEMMAP_GPA + 0x1000)
#define XJ380_MTRR_GPA (XJ380_BOOTCFG_GPA + 0x1000)
#define XJ380_STACK_GPA (XJ380_MTRR_GPA + 0x2000) /* 8KB guest 启动栈 */
#define XJ380_FAKEEFI_GPA (XJ380_STACK_GPA + 0x2000)
#define XJ380_FBC_GPA (XJ380_FAKEEFI_GPA + 0x1000)
#define XJ380_BOOT_AREA_SIZE (XJ380_FBC_GPA + 0x1000 - XJ380_BOOT_AREA_GPA) /* 至 FBC 结束 */
#define XJ380_BOOT_STACK_TOP (XJ380_STACK_GPA + 0x2000)
#define XJ380_GUEST_FB_GPA 0x00100000ULL /* 1MB */
#define XJ380_FB_WIDTH 1024
#define XJ380_FB_HEIGHT 768
#define XJ380_FB_BPP 4
#define XJ380_FB_SIZE ((u64)XJ380_FB_WIDTH * XJ380_FB_HEIGHT * XJ380_FB_BPP)
#define XJ380_GUEST_KERNEL_GPA 0x01000000ULL /* 16MB */
#define XJ380_GUEST_KERNEL_MAX (32 * 1024 * 1024) /* 内核窗口 16MB..48MB */
#define XJ380_GUEST_RAM_GPA 0x03000000ULL /* 48MB */
#define XJ380_GUEST_RAM_SIZE 0x40000000ULL /* 1GB (0x03000000..0x43000000) */
#define XJ380_GUEST_RAM_MIN 0x10000000ULL /* 降级下限 256MB */
/* BOOT_CONFIG.boot_flags(与 OpenXJ380 boot/include/boot.h 一致) */
#define XJ380_BOOT_FLAG_DISABLE_KMOD (1ULL << 2)
#define XJ380_BOOT_FLAG_SAFE_STORAGE_IO (1ULL << 3)
/* ===== 加载后的 XJ380 guest 状态 ===== */
struct xj380_guest_info {
u64 kernel_gpa; /* 内核段装入的 GPA 基址 */
u64 kernel_entry; /* 64 位入口(guest 虚拟地址 0xFFFFFFFF80000000+) */
u64 kernel_size; /* 内核跨度(memsz 上界 - 基址) */
u64 pgt_gpa; /* guest CR3(页表 GPA) */
u64 gdt_gpa; /* guest GDT GPA */
u64 ram_gpa; /* guest RAM GPA 基址 */
u64 ram_size; /* guest RAM 实际大小 */
u64 fb_gpa; /* framebuffer GPA */
int loaded; /* 1 = 加载成功 */
};
/* 在 Limine boot module 中查找 XJ380 内核(路径含 "xj380")。
* 返回模块数据指针,*size_out 为大小;未找到返回 NULL。 */
void *xj380_find_kernel_module(u64 *size_out);
/* 初始化 XJ380 guest:解析 ELF、分配内存、构造页表/GDT/ACPI 桩表/
* BOOT_CONFIG/内存图、EPT 映射。返回 0 成功,负值失败。 */
int xj380_loader_init(void);
/* 获取加载后的 guest 信息(未加载返回 NULL)。 */
const struct xj380_guest_info *xj380_get_guest_info(void);
/* 配置 VMCS 并 vmlaunch XJ380 guest。
* 前置条件:vmm_init() + xj380_loader_init()。
* guest 终止(异常/三重故障/0xCF9 重启)后返回;期间 host 挂起。
* 返回 0 表示 guest 终止返回,负值表示启动失败。 */
int xj380_launch(void);
#endif /* UTSM_XJ380_LOADER_H */