Files
Deshab-OS/CODE/linux/README.md
T
boonxiong2 1c99c77b3f fix(build): make the packed image actually bootable
There were three independent reasons a fresh build produced an image that
OVMF would not boot. All three are fixed here; verified by booting the
resulting ISO/deshab-dev.img under QEMU/OVMF through to FirstInit.

1. ESP rejected by OVMF (CODE/linux/pack_system_image.sh)
   The vfat formatter was invoked with an explicit -s 8, forcing 4KiB clusters.
   On the 256MiB ESP that yields exactly 65535 clusters - the FAT32 0xFFF5
   boundary - and OVMF's FatPkg refuses to mount the volume. Symptom: BdsDxe
   logs "failed to load ... Not Found", the ESP shows up as BLKn with no FS in
   the UEFI Shell, and the firmware falls through to the internal shell.
   The sidecar FAT32 image (make_sata_sidecar.sh) mounts fine because it calls
   the formatter without -s. Drop -s here too and let the tool pick geometry.
   Do NOT add -f 1: OVMF mounts nfat=1 and nfat=2 alike, it was not the cause.

2. Limine dropped into a panic (CODE/linux/pack_system_image.sh)
   limine.conf declares the Linux-compat guest modules. build.sh uncomments
   them once Linux has been built, but nothing ever comments them back, so the
   file says "load boot():/boot/linux-initrd.img" while only linux-bzImage
   exists on disk - Limine panics on the missing module and never reaches the
   kernel. Filter the guest module_path lines against SYSTEM/boot/ at pack
   time and write the result to the ESP. Both the root /limine.conf and
   /limine/limine.conf are written, since Limine 10 prefers the latter. The
   tracked source file is left untouched.

3. Nine drivers were never compiled (build.ps1)
   Commit 055c521 untracked the .drv binaries on the grounds that they are
   regenerable, but build.ps1 only ever invoked Build-DkmDriver for 8 of the
   17 drivers listed in manifest.json. timer/acpi/pci/ahci/bootfs/vfs/fat32/
   devfs/ps2kbd had sources under CODE/DKM/ and no build step, so the image
   shipped without them and Limine failed on the first one. Add the missing
   compile steps, grouped by load stage. All 17 now match manifest.json.

Also in this commit (environment/tooling hygiene):
- check_env.sh: stop hardcoding /mnt/d/Code/Deshab (the original author's
  machine); derive the repo root from the script's own location. It was
  reporting a bogus "wsl_mount" failure on every other checkout and sending
  people to install packages that were already present. Also check and
  advertise the image-packing tools (dosfstools/e2fsprogs/fdisk/rsync), which
  were missing from the dependency list even though pack_system_image.sh
  hard-requires them.
- build_initrd.sh: same hardcoded-path fix.
- README.md: relative path instead of the stale absolute one.

Verified: ./build.bat -Variant dev under WSL2/Ubuntu, then QEMU/OVMF boots
through BdsDxe -> Limine -> UTSM -> DKM (17/17) -> DSK -> FirstInit, with the
PS/2 mouse initialising cleanly.
2026-10-05 14:03:39 +08:00

5.4 KiB
Raw Blame History

Linux 6.6 LTS for UTSM Dual-Kernel Architecture

Overview

This directory contains the Linux 6.6 LTS configuration and build scripts for the UTSM + Linux dual-kernel architecture. Linux runs as a VMX non-root guest under the UTSM hypervisor (VMX root).

Prerequisites

  • WSL (Windows Subsystem for Linux) with Ubuntu 22.04+ installed
    wsl --install -d Ubuntu-22.04
    
  • Build dependencies (inside WSL):
    sudo apt update
    sudo apt install -y build-essential bc flex bison libelf-dev libssl-dev cpio gzip git
    
  • ~3GB free disk space

Building Linux

1. From WSL

# Navigate to the project from your repo root in WSL
cd CODE/linux

# Make the build script executable
chmod +x build.sh

# Run the build (clones Linux 6.6 LTS, configures, builds)
./build.sh

The build will:

  1. Clone Linux 6.6 LTS source to CODE/linux/src/
  2. Apply UTSM patches from CODE/linux/patches/ (if any)
  3. Configure with configs/utsm_x86_64_defconfig
  4. Build bzImage
  5. Copy to SYSTEM/boot/linux-bzImage
  6. Build initramfs if CODE/linux/initramfs/ exists

2. Enable in Limine

After building, uncomment the Linux module entries in SYSTEM/limine/limine.conf:

    module_path: boot():/boot/linux-bzImage
    module_cmdline: linux:bzImage
    module_path: boot():/boot/linux-initrd.img
    module_cmdline: linux:initrd

3. Rebuild the disk image

cd d:\Code\Deshab
.\build.bat

4. Test with QEMU

Note: VMX requires hardware virtualization support. QEMU's TCG (software emulation) does NOT support VMX instructions. To test the VMX path:

  • Real hardware: Boot on an Intel machine with VT-x enabled in BIOS
  • QEMU with WHPX: qemu-system-x86_64 -accel whpx -cpu max (may not expose nested VMX to the guest)
  • QEMU with KVM (Linux host only): qemu-system-x86_64 -enable-kvm -cpu host

Without VMX, UTSM gracefully falls back to the normal DSK boot flow.

Configuration Details

The utsm_x86_64_defconfig enables:

  • 64-bit kernel with SMP support
  • Serial console (8250/16550 at 0x3F8, 115200 baud)
  • virtio: console, block, net, fs (for UTSM host backends)
  • ext4, FAT, tmpfs, proc, sysfs filesystems
  • No module loading (all drivers built-in for Phase 1)
  • No EFI stub (UTSM uses custom VMX boot protocol)
  • Debug info and printk timestamps

File Structure

CODE/linux/
├── configs/
│   └── utsm_x86_64_defconfig   # Kernel configuration
├── patches/                     # UTSM-specific kernel patches
│   ├── utsm-hcall.patch         # /dev/utsm hypercall driver (Phase 1.3)
│   ├── utsm-ipc.patch           # Shared memory IPC driver (Phase 1.3)
│   └── utsm-virtio.patch        # virtio enhancements (Phase 1.4+)
├── initramfs/                   # Minimal initramfs contents (optional)
├── build.sh                     # Build script (run in WSL/Linux)
└── README.md                    # This file

Boot Flow

Limine (UEFI)
  → utsm.elf (VMX root)
    → vmm_init() + vmm_self_test()
    → linux_loader_init() (parse bzImage, set up boot_params, EPT)
    → linux_launch() (VMCS config + vmlaunch)
      → Linux 6.6 startup_64 (VMX non-root)
        → Serial console output
        → virtio-console ↔ UTSM
        → virtio-fs mount /utsm
        → User space (init/shell)

Guest Networking (virtio-net)

UTSM vmm 侧模拟一块 virtio-net 网卡(virtio-mmio 模型,GPA 0xF4001000, guest ISA IRQ6),数据路径桥接到 host 真实网卡(e1000/virtio-net DKM 驱动, 经 kernel_api.net 的 tx/rx_poll 收发帧)。guest 内核 cmdline 已自动注入:

virtio_mmio.device=4K@0xF4001000:6

utsm_x86_64_defconfig 已启用 CONFIG_VIRTIO_NET=y(内置,非模块), 内核启动后应出现 eth0(virtio-mmio 无 PCI 拓扑,网卡名固定为 eth0):

# 确认网卡已识别(dmesg 应能看到 virtio_net  probe 日志)
ip link show

# 拉起接口
ip link set eth0 up

# 方式一:DHCP(QEMU user-net/slirp 环境,网关 10.0.2.2,DNS 10.0.2.3)
dhcpcd eth0
# 或:dhclient eth0

# 方式二:静态地址(无 DHCP 服务器时)
ip addr add 10.0.2.15/24 dev eth0
ip route add default via 10.0.2.2
echo "nameserver 10.0.2.3" > /etc/resolv.conf

# 验证连通性
ping -c3 10.0.2.2        # QEMU slirp 网关(永远在线,适合冒烟测试)
ping -c3 10.0.2.3        # slirp 内建 DNS
pacman -Sy               # 联网同步包数据库

注意事项:

  • MAC 共用:guest virtio-net 的 MAC 与 host e1000 相同(UTSM 桥接模型, config 空间直接回填 host 网卡 MAC)。QEMU user-net 下 slirp 按 MAC 分配 10.0.2.15;若 host Deshab 原生网络栈同时用该网卡联网,两者会抢同一 DHCP 租约,实测时请只让一侧做 DHCP(或 host 完全不用网络)。
  • MTU:后端按标准 1500 MTU 转发,不支持 GSO/TSO(feature 未协商, guest 自动走软件分片/checksum 路径)。
  • 无中断收包:RX 走 UTSM 周期轮询(VMX preemption timer,~1kHz) 填充 guest RX ring 并注入 IRQ6;大流量下串口统计日志每 512 帧打印一行 [VNET] stat ...(rx_filled / rx_drop_nobuf / tx_sent / tx_drop), 可用于判断包在哪一段丢失。
  • 若 ip link 看不到 eth0:检查 dmesg 中 virtio_mmio probe 是否成功, 以及 host 串口日志是否有 [VNET] bound to UTSM net device 0 (host 侧 e1000/virtio-net DKM 驱动需先注册 netdev)。