Files
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

166 lines
5.4 KiB
Markdown
Raw Permalink 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.
# 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
```powersShell
wsl --install -d Ubuntu-22.04
```
- Build dependencies (inside WSL):
```bash
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
```bash
# 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
```PowerShell
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):
```bash
# 确认网卡已识别(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)。