Files
Deshab-OS/CODE/linux
boonxiong2 780230599d fix(dsk,firstInit,build): let the system boot all the way to the desktop
Four independent blockers sat between "the image boots UTSM" and "the desktop
comes up". Each one wedged the boot on its own; all four are fixed here and the
tree now reaches "[desktop] desktop ready" under QEMU/OVMF
(evidence: .build_tmp/d2.log).

1. FirstInit made networking a hard gate (CODE/firstInit/main.c)
   The setup wizard always showed the network page, and on a machine with no
   wireless device the only exit was Save - pressing Connect raised NET-E01.
   Networking is not a precondition for entering the system, so a wizard that
   cannot be completed without it is a plain design defect.
   - No wireless device detected -> skip the network page entirely (the
     g_no_wireless_device flag already existed but was only logged).
   - With a device present, add a Skip button (draw + mouse hit-box + keyboard
     Enter), mirroring "I don't have internet" on Windows.
   - Connect keeps its zero-fallback NET-E01 panic: the unimplemented path is
     still honest, it just no longer holds the user hostage.

2. ESP cluster size left no room in the root directory
   (CODE/linux/pack_system_image.sh)
   With the cluster size left to mkfs it chose 1 sector, i.e. 16 directory
   entries per cluster. The ESP root ends up holding exactly 16 entries
   (DESHABBOOT/EFI/LIMINE/BOOT/DRIVER/SYSTEM/USER/NVVARS plus one long-name
   entry each), and the root chain is a single cluster - so on first boot the
   DSK could never write USER.CONF.
   Pin -s 4 (2KiB, 64 entries): it clears the FAT32 65525 lower bound and the
   0xFFF5 boundary that -s 8 lands on at this 256MiB size, and leaves 48 free
   entries. The alternatives were measured, not guessed (see the comment).

3. DSK could not grow the root directory (CODE/dsk/main.c)
   fat32_write_root_file returned -4 "no free dir entry" whenever the scan of
   the root chain came up empty. A FAT filesystem is supposed to extend the
   directory chain, so allocate a cluster, link it at the current tail, write
   the entry there and commit the FAT. Fixing only (2) would have papered over
   this: any real disk whose root fills up would still fail the same way.

4. Nothing generated the CJK bitmap font packs (build.ps1)
   The desktop loads system/font/simhei_16.dbf and panics DESK-E04 FONT PACK
   MISSING without it. The .dbf files are generated from simhei.ttf by
   CODE/font/mkfont.py and are gitignored, but no build step ever invoked it -
   same class of bug as the previously untracked .drv binaries. Generate
   simhei_16.dbf / simhei_24.dbf in build.ps1 (with the existing WSL python3
   fallback for Pillow), rebuilding only when the TTF is newer than the pack.

docs/STATUS.md updated to match: FirstInit wizard and the D3 named API export
table move to done, and the FAT32 / ESP cluster size / CJK font pack entries
are added or corrected. D3 was already fully implemented (table, lookup,
selftest with positive and negative cases, TST-E21..E24 instrumentation) -
only the status row was stale.

Verified boot chain (QEMU/OVMF, dev variant):
  BdsDxe -> Limine -> UTSM -> DKM 17/17 -> DSK -> FirstInit (network page
  skipped) -> USER.CONF written -> login (password accepted) -> desktop:
  "[zhfont] dbf loaded (16px ok)" ... "[desktop] desktop ready"
2026-10-05 18:32:24 +08:00
..
2026-08-09 22:20:01 +08:00
2026-07-28 21:11:10 +08:00
2026-07-28 21:11:10 +08:00

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)。