# Deshab 兼容层设计文档 > Linux程序兼容层(双内核park-and-resume)与PE/EXE兼容层(UTSM内置加载器),以及Pacman生态方案。 --- ## 1. 概述 Deshab无Linux syscall/动态链接器/Windows API,兼容走两条路线: | 兼容层 | 目标 | 路线 | 类比 | |--------|------|------|------| | Linux兼容层 | Linux x86-64 ELF | UTSM作VMM运行Linux 6.6 guest,Deshab经IPC委托执行取回结果 | WSL | | PE/EXE兼容层 | PE32+/PE32 | UTSM内置PE加载器+API shim+x86-32解释器,Ring0直接执行 | 极简Wine | 核心判断:pacman装的软件是Linux动态链接ELF,不可能在Deshab原生跑。正确模式:Linux guest内Arch+pacman→Deshab通过IPC委托Linux执行→结果显示回Deshab。 --- ## 2. 双内核架构 ### 2.1 park-and-resume模型 UTSM作VMM(VMX root),Linux 6.6 LTS作guest(VMX non-root)常驻内存。 ```text UTSM(Ring0) → linux_compat_service.exec() → 写EXEC_REQUEST到utsm_to_linux ring → linux_resume() → vmresume → Linux guest(daemon: RECV_MSG→fork+exec→pipe捕获输出 → SEND_MSG STDOUT/STDERR/EXIT → ioctl(PARK)→HLT→VM-Exit) ← VM-Exit(HLT) → host推进RIP → 从linux_to_utsm ring读输出 ``` - **park**:guest HLT→VM-Exit→host推进RIP+exit-to-host(`g_guest_parked=1`) - **resume**:`linux_resume()`经vmresume唤醒parked guest - guest cmdline须含`nohlt idle=poll`:防止内核idle的HLT误触发park ### 2.2 组件清单 | 组件 | 文件 | |------|------| | VMM | `vmm.c/vmx.c/ept.c`, `vmexit.c/vmexit_asm.S` | | Linux装载 | `linux_loader.c/linux_boot.c` | | 唤醒 | `linux_resume.c` | | 兼容服务 | `linux_compat.c`+`linux_compat.h` | | IPC | `CODE/utsm-ipc/ipc_proto.h` | | virtio后端 | `virtio_mmio.c/virtio_blk.c/virtio_net.c` | | Linux侧驱动 | `CODE/linux/patches/utsm_hcall.c` | | exec daemon | `CODE/linux/initramfs/bin/utsm_exec_daemon.c` | ### 2.3 guest构建产物 | 产物 | 位置 | 说明 | |------|------|------| | bzImage | `SYSTEM/boot/linux-bzImage` | Limine boot module | | initramfs | `SYSTEM/boot/linux-initrd.img` | phase-1最小用户态(init+daemon) | | Arch rootfs | `SYSTEM/boot/linux-rootfs.img` | virtio-blk /dev/vdb,含pacman+国内镜像 | --- ## 3. Guest GPA内存布局 定义于`CODE/UTSM/include/utsm/linux_loader.h`: | GPA范围 | 用途 | |----------|------| | 0x00000000–0x003FFFFF | UTSM保留 | | 0x00400000 | boot_params(4KB) | | 0x00500000 | 内核cmdline(≤4096B) | | 0x00600000/0x00700000/0x00800000 | guest GDT/页表/栈 | | 0x01000000–0x02FFFFFF | Linux内核镜像(2MB对齐) | | 0x03000000–0x03FFFFFF | initrd | | **0x04000000–0x040FFFFF** | **IPC共享内存(1MB)** | | 0x05000000+ | Linux通用RAM | | 0xF4000000/0xF4001000/0xF4002000 | virtio-mmio blk(IRQ5)/net(IRQ6)/rootfs(IRQ7) | virtio-mmio设备区EPT故意不映射→EPT violation→vmexit路由到后端模拟。guest经cmdline `virtio_mmio.device=4K@:`发现设备。 guest cmdline:`console=ttyS0,115200 earlyprintk=serial nokaslr no_timer_check loglevel=7 nohlt idle=poll noapic nolapic nosmp virtio_mmio.device=4K@0xF4000000:5 virtio_mmio.device=4K@0xF4001000:6 virtio_mmio.device=4K@0xF4002000:7` --- ## 4. VMCS与VM-Exit处理 - VMCS不保存guest GPR,`vmexit_asm.S`保存16个GPR到`g_guest_regs`,vmresume前恢复 - VMCALL约定:a0=rdi, a1=rsi, a2=rdx,返回值写g_guest_regs.rax - host恢复点:`g_saved_host_rsp/g_saved_return_rip/g_guest_terminated/g_last_exit_reason`(须非static全局变量) 已处理退出原因: | Exit reason | 处理 | |-------------|------| | HLT | Linux→park(推进RIP);自检→terminate | | EPT_VIOLATION | GPA在virtio-mmio区→模拟;否则EPT动态映射 | | CPUID | 直通+屏蔽VMX/hypervisor位 | | IO_INSTRUCTION | 端口I/O模拟 | | INTERRUPT_WINDOW | 注入待决虚拟IRQ | | VMX_PREEMPTION_TIMER | 周期调virtio_net_poll()填充RX buffer | | VMCALL | hypercall分发 | --- ## 5. IPC协议 唯一定义在`CODE/utsm-ipc/ipc_proto.h`(`__UTSM_KERNEL__`/`__KERNEL__`条件包含)。 ### 5.1 共享内存布局(GPA 0x04000000, 1MB, packed) ```text 0x04000000 utsm_ipc_shm_header 64B(magic "UTSMHC\0\0"+version+握手位) 0x04000040 utsm_to_linux ring 16400B(UTSM写,Linux读) 0x04004050 linux_to_utsm ring 16400B(Linux写,UTSM读) 0x04008060 payload_pool 1015712B(批量数据缓冲) ``` 每ring:64槽×256B消息(16B头+240B inline data)。单生产者单消费者,head/tail volatile+内存屏障。 ### 5.2 三条通信通道 1. 共享内存ring(异步双向) 2. VMCALL hypercall(同步请求/响应) 3. IPI通知(UTSM→Linux经guest IRQ注入) ### 5.3 消息类型 | 类型 | 值 | 方向/说明 | |------|----|-----------| | HELLO/HELLO_ACK | 1/2 | 握手 | | PING/PONG | 3/4 | 连通性 | | EXEC_REQUEST | 16 | UTSM→Linux: ipc_exec_request{argc,flags,path[128],argv_blob[96]} | | EXEC_STDOUT/STDERR | 17/18 | Linux→UTSM: 裸字节流分块 | | EXEC_EXIT | 19 | Linux→UTSM: exit_code | | EXEC_READY | 20 | Linux→UTSM: daemon就绪 | | FILE_LIST/READ/WRITE_REQUEST | 24/25/27 | UTSM→Linux: 文件操作 | | FILE_RESPONSE | 26 | Linux→UTSM: status+data_len+total_size | ### 5.4 hypercall操作 | op | 值 | 说明 | |----|----|------| | PING/HELLO | 0x0001/0x0002 | 连通性 | | SHM_INFO | 0x0010 | 查询共享内存GPA+size | | CAP_VALIDATE | 0x0020 | capability校验 | | UTRW_READ/WRITE | 0x0030/0x0031 | 封缄内存读写 | | DRR_CHECKPOINT | 0x0040 | 触发checkpoint | | CONSOLE_WRITE/READ | 0x0050/0x0051 | 串口控制台 | | **FILE_READ** | 0x0060 | 读UTSM FAT32文件到payload_pool(a0=文件名GPA,a1=偏移,a2=最大字节;RAX低20位=暂存字节,高位=总大小) | | **FILE_WRITE** | 0x0061 | payload_pool写为FAT32文件(整文件替换) | 单文件≤256KB;payload_pool为单写者通道,禁止并发。 ### 5.5 文件传输协议 - 读/列目录:UTSM写请求→linux_resume→daemon opendir/readdir或open/pread→数据写进payload_pool→FILE_RESPONSE→HLT park - 写:UTSM预摆数据进payload_pool→daemon读出pwrite(offset 0以O_TRUNC打开) - payload_pool≈1MB,单次往返最多~1MB,更大文件按递增file_offset循环 - 状态码:OK=0, NOENT, IO, NOTDIR, ISDIR, PERM, INVAL, NOSPC --- ## 6. virtio-mmio设备模拟 Virtio Spec 1.1 §4.2,32位寄存器。框架`virtio_mmio.c`,后端`virtio_blk.c`/`virtio_net.c`。 - guest访问设备GPA→EPT violation→handle_virtio_mmio_access→按GPA定位设备+按偏移模拟寄存器 - 后端注册表`struct virtio_backend{device_id,gpa_base,irq,num_queues,queue_size,device_features,config_len,read_config,queue_notify,reset}` - virtqueue split ring(desc 16B/avail/used) - `virtio_gpa_to_host()`:EPT翻译GPA→HPA+HHDM offset - 中断:置INTERRUPT_STATUS bit0+注入虚拟IRQ(blk→5,net→6,rootfs→7, vector=0x30+irq) - net RX异步路径:VMX preemption timer周期调virtio_net_poll()填充guest RX buffer+注入IRQ - blk后端已支撑guest挂载Arch rootfs(/dev/vdb) --- ## 7. Linux兼容层服务接口 `linux_compat_service`(magic "LNXCOMP\0")经`dsk_boot_context.reserved[5]`暴露: | 接口 | 说明 | |------|------| | is_available() | guest已park+IPC就绪 | | exec(path,argc,argv,stdout_buf,cap,len,exit_code) | 执行Linux程序取回stdout/exit_code | | file_list/read/write(path,...) | 列目录/分块读/分块写Linux文件 | | file_pull/push(linux_path,fat32_name,...) | Linux文件↔UTSM FAT32根目录(≤256KB) | | status(buf,cap) | guest状态字符串 | shell命令:`dsl [args]`(Tab可补全Linux程序名)、`dsl push/pull`、`dsl ls [path]`、`dsl cat ` --- ## 8. Linux guest侧组件 **utsm_hcall驱动**:VMCALL发起hypercall;/dev/utsm ioctl: RECV_MSG/SEND_MSG/PARK/GET_READY/WRITE_POOL/READ_POOL **exec daemon**(PID 2):启动→发EXEC_READY→ioctl(PARK)→HLT;循环:vmresume唤醒→RECV_MSG→处理(EXEC_REQUEST:fork+exec+pipe; FILE_*:opendir/open/pread/pwrite)→ioctl(PARK) --- ## 9. PE/EXE兼容层 四组件经`dsk_boot_context.reserved[4]`暴露`pe_service`(magic "PESVC\0\0",接口load/run/unload): | 组件 | 职责 | |------|------| | pe_loader.c | DOS/NT头校验+节区映射+重定位+import表解析 | | pe_shim.c | Windows API shim(ms_abi包装)+IAT填充 | | x86emu32.c | x86-32解释器(PE32执行引擎) | | pe_service.c | 服务装配+执行策略 | 执行策略: - **PE32+**:重定位加载→IAT填ms_abi shim→Ring0原生执行;ExitProcess经__builtin_longjmp跳回 - **PE32**:preferred_base直接加载(64KB栈+256KB堆)+IAT填合成地址(0x00010000|shim_idx)→x86emu32解释执行。约束:镜像≤64MB, preferred_base≤0x10000000, IAT≤256项 安全方向:PE shim白名单+IAT拦截审计。 --- ## 10. Pacman五阶段方案 | 阶段 | 内容 | 状态 | |------|------|------| | 1. Linux guest跑起来 | virtio-blk/net+initramfs/rootfs+EPT动态映射 | ✅ | | 2. guest内Arch+pacman | Arch bootstrap rootfs+国内mirrorlist | ✅(网络下载待联网验证) | | 3. UTSM↔Linux文件传输IPC | FILE_READ/WRITE hypercall+ring分块+shell接入 | ✅(代码全链路就绪) | | 4. shell命令委托执行 | IPC exec(16–20)+daemon fork/exec | ✅(全链路已验证) | | 5. desktop集成 | app_descriptor.linux_cmd+LINUXAPP.CNF | ✅ | **最大遗留项:VMX实机验证**(需嵌套虚拟化环境)。WHPX不支持嵌套VMX,已通过vmx_truly_available()检测+QEMU -cpu qemu64,-vmx规避,无VMX时linux命令优雅降级。 --- ## 11. 实现状态总览 | 能力 | 状态 | |------|------| | VMM(VMX/EPT/VMCS/VM-Exit) | ✅ | | Linux guest装载与启动 | ✅ | | park-and-resume | ✅ | | IPC(ring+hypercall+payload_pool) | ✅ | | virtio-mmio blk/rootfs | ✅ | | virtio-mmio net | 🔶(后端框架+RX poll) | | linux_compat_service | ✅ | | PE32+/PE32执行 | ✅ | | VMX实机验证 | ❌ |