Files
Deshab-OS/CODE/utsm-ipc
2026-08-09 22:20:01 +08:00
..
2026-08-09 22:20:01 +08:00
2026-07-28 12:00:02 +08:00

UTSM ↔ Linux IPC 骨架 (Phase 1.3)

概述

Phase 1.3 实现了 UTSM 监控核与 Linux 主导核之间的双向 IPC 通信骨架,包含三个通信通道中的两个:

  1. 共享内存环形缓冲区(异步消息) — ✅ 已实现
  2. VMCALL hypercall(同步请求/响应) — ✅ 已实现
  3. IPI 通知(中断注入) — ⏳ Phase 1.4+

文件结构

UTSM 侧(监控核)

CODE/UTSM/
├── include/utsm/
│   ├── ipc_shm.h         — IPC 共享内存 API 声明
│   └── hypercall.h       — VMCALL 处理器 API 声明
├── vmm/
│   ├── ipc_shm.c          — 共享内存分配、初始化、EPT 映射、ring buffer 操作
│   ├── hypercall.c        — VMCALL VM-Exit 处理(PING/HELLO/SHM_INFO/CONSOLE_WRITE)
│   ├── vmexit.c           — VM-Exit 分发器(增加 VMCALL case)
│   ├── vmexit_asm.S       — VM-Exit 汇编入口(重写:保存/恢复 guest GPR + 汇编 vmresume)
│   ├── vmm.c              — VMM 核心(g_guest_regs 全局变量 + vmm_vmexit_entry 简化)
│   └── ept.c              — EPT 页表(增加 ept_gpa_to_hpa() 翻译函数)

共享协议

CODE/utsm-ipc/
└── ipc_proto.h            — 双内核共享的 IPC 协议头文件

Linux 侧(主导核)

CODE/linux/
├── configs/
│   └── utsm_x86_64_defconfig  — 增加 CONFIG_UTSM_HCALL=y
├── patches/
│   ├── utsm_hcall.c       — Linux 内核驱动:VMCALL + /dev/utsm + SHM 映射
│   ├── utsm_Kconfig       — Kconfig 配置
│   └── utsm_Makefile      — 模块 Makefile
└── build.sh               — 更新:自动安装驱动到 Linux 源码树

通信协议

共享内存布局(GPA 0x04000000,1MB)

0x04000000  utsm_ipc_shm_header (64 bytes)
            ├── magic = "UTSMHC\0\0"
            ├── version = 1
            ├── utsm_ready (UTSM 设置)
            └── linux_ready (Linux 设置)

0x04000040  utsm_ipc_ring utsm_to_linux (UTSM 写,Linux 读)
            └── 64 条消息,每条 256 字节

0x04001040  utsm_ipc_ring linux_to_utsm (Linux 写,UTSM 读)
            └── 64 条消息,每条 256 字节

0x04002040  payload pool (~1MB,用于大数据传输)

VMCALL Hypercall ABI

Linux guest 执行 VMCALL 指令:
  RAX = UTSM_HCALL_MAGIC | op   (0x5554534D48430000 | op)
  RDI = arg0
  RSI = arg1
  RDX = arg2

UTSM 处理 VMCALL VM-Exit:
  1. 从 g_guest_regs 读取 RAX/RDI/RSI/RDX
  2. 验证 magic,提取 op
  3. 分发到对应处理器
  4. 返回值写入 g_guest_regs.rax
  5. GUEST_RIP 前进过 VMCALL 指令
  6. vmresume(GPR = 修改后的 guest 值)

已实现的 Hypercall 操作

操作码 名称 功能
0x0001 PING 返回 "PONG" (0x504F4E47),用于探测 UTSM
0x0002 HELLO 握手,UTSM 回复 HELLO_ACK 消息到 ring
0x0010 SHM_INFO 返回共享内存 GPA + size
0x0020 CAP_VALIDATE 能力校验(stub)
0x0030 UTRW_READ 封缄内存读(stub)
0x0031 UTRW_WRITE 封缄内存写(stub)
0x0040 DRR_CHECKPOINT DRR checkpoint 触发(stub)
0x0050 CONSOLE_WRITE 将 Linux 字符串输出到 UTSM 串口
0x0051 CONSOLE_READ 从 UTSM 串口读取(stub)

关键设计决策

1. VM-Exit 汇编重写

VMCS 不保存 guest GPR(RAX-R15)。原汇编只保存 host caller-saved 寄存器,无法让 C 处理器读写 guest GPR。

重写后:

  • VM-Exit 时保存全部 16 个 guest GPR 到 g_guest_regs 结构
  • 调用 C 分发器(不再从 C 调用 vmresume)
  • 恢复全部 16 个 guest GPR(C 可能已修改 rax = 返回值)
  • 汇编中执行 vmresume(GPR = 修改后的 guest 值)

2. EPT GPA→HPA 翻译

Linux guest 使用 identity-mapped 页表(GVA=GPA),hypercall 传递的指针是 GPA。UTSM 需要:

  • ept_gpa_to_hpa(gpa) — 4 级 EPT walk,支持 4KB/2MB/1GB 页
  • 翻译后加 HHDM 偏移得到 host 虚拟地址

3. GPA 布局修复

原 LINUX_GUEST_INITRD_GPA = 0x04000000 与 UTSM_IPC_SHM_GPA = 0x04000000 冲突。

修复后:

0x00400000-0x004FFFFF  固定区域 (boot_params/cmdline/GDT/PGT/stack)
0x01000000-0x02FFFFFF  Linux kernel
0x03000000-0x03FFFFFF  initrd
0x04000000-0x040FFFFF  IPC shared memory (1MB) ← e820 reserved
0x05000000-0x08FFFFFF  general RAM (64MB)

验证方法

1. UTSM 侧编译验证(已完成)

cd d:\Code\Deshab\CODE\UTSM
mingw32-make
# → utsm.elf 生成,0 warnings from new code

2. Linux 内核构建(需 Linux 环境)

cd CODE/linux
./build.sh
# → SYSTEM/boot/linux-bzImage
# → SYSTEM/boot/linux-initrd.img

3. QEMU 端到端测试(需 VMX 支持)

  1. 取消 SYSTEM/limine/limine.conf 中 Linux 模块的注释
  2. 运行 ISO/run_qemu.bat(需 KVM 或硬件 VMX)
  3. 预期串口输出:
    • [UTSM] IPC shm init ok
    • [LINUX] loader init ok
    • [LINUX] vmlaunch
    • Linux 启动日志
    • [utsm] UTSM monitor detected (PONG=0x504F4E47)
    • [utsm] /dev/utsm registered (IPC ready)
    • [HCALL] HELLO from Linux guest
  4. Linux 用户态测试:
    echo "hello UTSM" > /dev/utsm    # → UTSM 串口显示 [LINUX] hello UTSM
    cat /dev/utsm                     # → 读取 UTSM 发来的消息
    

后续阶段

  • Phase 1.4: virtio-console 双向通信(/dev/hvc0 ↔ UTSM 串口)
  • Phase 1.5: virtio-fs 文件共享(Linux 挂载 /utsm)
  • IPI 中断注入(替代当前的轮询方式)
  • UTRW/CAP/DRR hypercall 完整实现