diff --git a/CODE/linux/README.md b/CODE/linux/README.md index 30a98cd..f67d5ef 100644 --- a/CODE/linux/README.md +++ b/CODE/linux/README.md @@ -24,8 +24,8 @@ the UTSM hypervisor (VMX root). ### 1. From WSL ```bash -# Navigate to the project (adjust path for your WSL mount) -cd /mnt/d/Code/Deshab/CODE/linux +# Navigate to the project from your repo root in WSL +cd CODE/linux # Make the build script executable chmod +x build.sh diff --git a/CODE/linux/build_initrd.sh b/CODE/linux/build_initrd.sh index 4bcc923..6fbc67c 100644 --- a/CODE/linux/build_initrd.sh +++ b/CODE/linux/build_initrd.sh @@ -2,8 +2,9 @@ # Build initramfs only (assumes bzImage already built) set -e -SCRIPT_DIR="/mnt/d/Code/Deshab/CODE/linux" -PROJECT_ROOT="/mnt/d/Code/Deshab" +# 按脚本自身位置推导,不认死盘符路径。 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" OUTPUT_DIR="$PROJECT_ROOT/SYSTEM/boot" INITRAMFS_DIR="$SCRIPT_DIR/initramfs" LINUX_SRC="${LINUX_SRC:-$HOME/linux-6.6}" diff --git a/CODE/linux/check_env.sh b/CODE/linux/check_env.sh index 3c3d38a..8cf6640 100644 --- a/CODE/linux/check_env.sh +++ b/CODE/linux/check_env.sh @@ -5,7 +5,7 @@ # 用途: 在 WSL/Linux 中运行,验证构建 Linux 6.6 LTS bzImage 所需依赖 # # 使用: -# ! wsl bash /mnt/d/Code/Deshab/CODE/linux/check_env.sh +# ! wsl bash CODE/linux/check_env.sh # # 退出码: # 0 = 所有依赖已满足 @@ -16,6 +16,10 @@ set -e echo "[check] Linux 内核构建环境检查" echo "[check] ===========================" +# 仓库根目录:按脚本自身位置推导,不依赖当前工作目录,也不认死任何盘符路径。 +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +echo "[check] 仓库根: $REPO_ROOT" + # 1. 检查操作系统 if [ -f /etc/os-release ]; then . /etc/os-release @@ -40,6 +44,18 @@ for pkg in build-essential bc flex bison libelf-dev libssl-dev cpio gzip git; do fi done +# 2b. 检查镜像打包工具(pack_system_image.sh 硬依赖,不在上面那组内核依赖里) +echo "[check]" +echo "[check] 检查镜像打包工具..." +for pkg in dosfstools e2fsprogs fdisk rsync; do + if dpkg -s "$pkg" >/dev/null 2>&1; then + echo "[check] ✓ $pkg" + else + echo "[check] ✗ $pkg (缺失)" + MISSING+=("$pkg") + fi +done + # 3. 检查 gcc 版本 echo "[check]" echo "[check] 工具链版本:" @@ -60,7 +76,7 @@ fi # 4. 检查磁盘空间(需要 ~3GB) echo "[check]" -PROJECT_ROOT="/mnt/d/Code/Deshab" +PROJECT_ROOT="$REPO_ROOT" if [ -d "$PROJECT_ROOT" ]; then AVAILABLE_KB=$(df "$PROJECT_ROOT" | awk 'NR==2 {print $4}') AVAILABLE_GB=$((AVAILABLE_KB / 1024 / 1024)) @@ -73,13 +89,13 @@ if [ -d "$PROJECT_ROOT" ]; then fi fi -# 5. 检查访问 Windows D: 盘 +# 5. 检查 WSL 能否访问当前仓库(不认死盘符路径) echo "[check]" -if [ -d "/mnt/d/Code/Deshab" ]; then - echo "[check] ✓ WSL 可访问 /mnt/d/Code/Deshab" +if [ -d "$REPO_ROOT/CODE/linux" ] && [ -d "$REPO_ROOT/SYSTEM" ]; then + echo "[check] ✓ WSL 可访问当前仓库 ($REPO_ROOT)" else - echo "[check] ✗ WSL 无法访问 /mnt/d/Code/Deshab" - echo "[check] 请确认在 WSL 中执行,且 D: 盘已挂载" + echo "[check] ✗ WSL 无法访问当前仓库 ($REPO_ROOT)" + echo "[check] 请从仓库内运行本脚本,且 Windows 盘已挂载到 /mnt/<盘符>" MISSING+=("wsl_mount") fi @@ -107,11 +123,12 @@ if [ ${#MISSING[@]} -gt 0 ]; then echo "[check] 请运行以下命令安装依赖:" echo "[check] sudo apt update" echo "[check] sudo apt install -y build-essential bc flex bison libelf-dev libssl-dev cpio gzip git" + echo "[check] sudo apt install -y dosfstools e2fsprogs fdisk rsync" exit 1 fi echo "[check] ✓ 所有依赖已满足,可以构建 Linux 内核" echo "[check]" echo "[check] 下一步执行:" -echo "[check] cd /mnt/d/Code/Deshab/CODE/linux && chmod +x build.sh && ./build.sh" +echo "[check] cd $REPO_ROOT/CODE/linux && chmod +x build.sh && ./build.sh" exit 0 diff --git a/CODE/linux/pack_system_image.sh b/CODE/linux/pack_system_image.sh index 2770598..69f928d 100644 --- a/CODE/linux/pack_system_image.sh +++ b/CODE/linux/pack_system_image.sh @@ -167,13 +167,17 @@ if [[ -z "$p1" || -z "$p2" ]]; then exit 1 fi -# 4KiB clusters on a ~5GiB ESP; 32KiB if the ESP is 4GiB or larger. -fat_cluster_sectors=8 -if [[ "$esp_bytes" -ge $((4096 * 1024 * 1024)) ]]; then - fat_cluster_sectors=64 -fi - -mkfs.vfat -F 32 -n DESHABBOOT -s "$fat_cluster_sectors" "$p1" >/dev/null +# 簇大小交给 mkfs.vfat 自动选择。 +# +# 历史坑一:这里曾经强制 -s 8(4KiB 簇)。256MiB 的 ESP 恰好被算成 65535 +# 个簇(FAT32 的 0xFFF5 边界),该几何下 OVMF(EDK2 FatPkg) 拒挂该卷 —— +# 现象是 BdsDxe "Not Found",Shell 里分区只显示 BLKn、没有对应 FS。 +# 对照实验:sidecar(CODE/linux/make_sata_sidecar.sh)用不带 -s 的 +# mkfs.vfat 就一切正常,所以这里也不再手工指定簇大小。 +# +# 历史坑二:不要加 -f 1。UEFI 规范建议 ESP 用单 FAT 表,但实测 OVMF 对 +# nfat=1/2 都能挂,加 -f 1 并不能解决上面的问题,反而偏离 sidecar 的行为。 +mkfs.vfat -F 32 -n DESHABBOOT "$p1" >/dev/null # DSK 内嵌 ext4 读写驱动支持范围:4K block / 256B inode / extent 树, # 不支持 journal、metadata_csum、64bit(遇到即 panic FS-E28)—— # 因此这里必须显式关闭这三个 feature。 @@ -190,7 +194,54 @@ echo "[pack] copying p1 FAT32 ESP (EFI/ limine/ boot/ driver/ system/)" # vfat has no Unix owners/perms; -a would fail with rsync code 23. rsync -rltD --info=progress2 "$SYSTEM/EFI/" "$MNT_ESP/EFI/" rsync -rltD --info=progress2 "$SYSTEM/limine/" "$MNT_ESP/limine/" -cp -f "$SYSTEM/limine/limine.conf" "$MNT_ESP/limine.conf" + +# limine.conf 的 Linux 兼容层 module_path 段必须与 SYSTEM/boot/ 的实际产物一致。 +# CODE/linux/build.sh 建完 Linux 内核会自动取消那几行注释,但没有任何地方会关回去; +# 而 055c521 之后 .drv / Linux 产物都不入库,于是「注释开着但文件不存在」会让 +# Limine 直接 panic(Failed to open module ...),系统根本进不去。 +# 这里按实际存在的文件过滤后再写进 ESP —— 源文件 SYSTEM/limine/limine.conf 保持不动。 +# +# 注意:Limine 10 优先读 ESP 上的 /limine/limine.conf(目录形式),其次才是 +# 根目录 /limine.conf。上面 rsync 已经把未过滤的原版拷进 /limine/ 了,所以 +# 两处都必须写过滤后的副本,否则改根目录那份不起作用。 +filter_limine_conf() { + local dst="$1" + python3 - "$SYSTEM/limine/limine.conf" "$SYSTEM/boot" "$dst" <<'PYEOF' +import os, re, sys + +src, bootdir, dst = sys.argv[1], sys.argv[2], sys.argv[3] +# Linux/guest 内核段的 module_path(其它 module_path 靠路径前缀区分) +GUEST_PREFIXES = ('/boot/linux-', '/boot/xj380.krl') + +lines = open(src, 'r', encoding='utf-8').read().splitlines(keepends=True) +out, dropped, kept = [], [], [] + +for line in lines: + m = re.match(r'^(\s*)module_path:\s*boot\(\):(\S+)\s*$', line) + if m and m.group(2).startswith(GUEST_PREFIXES): + host = os.path.join(bootdir, m.group(2).split('/boot/', 1)[1]) + if os.path.exists(host): + kept.append(m.group(2)) + out.append(line) + else: + # 产物不存在 → 注释掉,避免 Limine 加载失败 panic + out.append('%s# [pack] module missing on disk, disabled: %s' % (m.group(1), line)) + dropped.append(m.group(2)) + else: + out.append(line) + +open(dst, 'w', encoding='utf-8').write(''.join(out)) +for p in kept: + print('[pack] limine module kept: %s' % p) +for p in dropped: + print('[pack] limine module DISABLED (file absent): %s' % p) +PYEOF +} + +mkdir -p "$MNT_ESP/limine" +filter_limine_conf "$MNT_ESP/limine.conf" # 根目录副本 +filter_limine_conf "$MNT_ESP/limine/limine.conf" # Limine 10 实际优先读的那份 + rsync -rltD --info=progress2 "$SYSTEM/boot/" "$MNT_ESP/boot/" rsync -rltD --info=progress2 "$SYSTEM/driver/" "$MNT_ESP/driver/" rsync -rltD --info=progress2 "$SYSTEM/system/" "$MNT_ESP/system/" diff --git a/build.ps1 b/build.ps1 index 721ca9a..0baf947 100644 --- a/build.ps1 +++ b/build.ps1 @@ -961,20 +961,40 @@ foreach ($tool in $toolApps) { Write-Host '[build] Building DKM framebuffer driver...' Build-DkmDriver (Join-Path $Root 'CODE\DKM\console_fb\console_fb.c') (Join-Path $SystemDir 'driver\console\console_fb.drv') +# stage0: platform + bus — timer 提供 PIT 校准,acpi 枚举 RSDP/XSDT,pci 扫描配置空间。 +# 这三个驱动 manifest.json 里是必需的;055c521 把它们从 git 移除后此处必须重新编译, +# 否则 limine 会 panic「Failed to open module boot():/driver/platform/timer.drv」。 +Write-Host '[build] Building DKM platform/bus drivers...' +Build-DkmDriver (Join-Path $Root 'CODE\DKM\timer\timer.c') (Join-Path $SystemDir 'driver\platform\timer.drv') +Build-DkmDriver (Join-Path $Root 'CODE\DKM\acpi\acpi.c') (Join-Path $SystemDir 'driver\platform\acpi.drv') +Build-DkmDriver (Join-Path $Root 'CODE\DKM\pci\pci.c') (Join-Path $SystemDir 'driver\bus\pci.drv') + # B7: apic.drv 纳入构建 (原 platform/apic.drv 为预置二进制, 不随 apic.c 更新) Write-Host '[build] Building DKM platform apic driver...' Build-DkmDriver (Join-Path $Root 'CODE\DKM\apic\apic.c') (Join-Path $SystemDir 'driver\platform\apic.drv') Write-Host '[build] Building DKM storage drivers...' +Build-DkmDriver (Join-Path $Root 'CODE\DKM\ahci\ahci.c') (Join-Path $SystemDir 'driver\block\ahci.drv') Build-DkmDriver (Join-Path $Root 'CODE\DKM\nvme\nvme.c') (Join-Path $SystemDir 'driver\block\nvme.drv') Build-DkmDriver (Join-Path $Root 'CODE\DKM\ehci\ehci.c') (Join-Path $SystemDir 'driver\block\ehci.drv') Build-DkmDriver (Join-Path $Root 'CODE\DKM\xhci\xhci.c') (Join-Path $SystemDir 'driver\block\xhci.drv') +# stage2: filesystem — bootfs 挂 boot module,vfs 汇总,fat32 只读 FAT32,devfs 暴露 /dev。 +Write-Host '[build] Building DKM filesystem drivers...' +Build-DkmDriver (Join-Path $Root 'CODE\DKM\bootfs\bootfs.c') (Join-Path $SystemDir 'driver\fs\bootfs.drv') +Build-DkmDriver (Join-Path $Root 'CODE\DKM\vfs\vfs.c') (Join-Path $SystemDir 'driver\fs\vfs.drv') +Build-DkmDriver (Join-Path $Root 'CODE\DKM\fat32\fat32.c') (Join-Path $SystemDir 'driver\fs\fat32.drv') +Build-DkmDriver (Join-Path $Root 'CODE\DKM\devfs\devfs.c') (Join-Path $SystemDir 'driver\fs\devfs.drv') + Write-Host '[build] Building DKM network drivers...' Build-DkmDriver (Join-Path $Root 'CODE\DKM\e1000\e1000.c') (Join-Path $SystemDir 'driver\net\e1000.drv') Build-DkmDriver (Join-Path $Root 'CODE\DKM\virtio_net\virtio_net.c') (Join-Path $SystemDir 'driver\net\virtio_net.drv') Build-DkmDriver (Join-Path $Root 'CODE\DKM\ath9k\ath9k.c') (Join-Path $SystemDir 'driver\net\ath9k.drv') +# stage3: input — ps2kbd 注册 IRQ1。 +Write-Host '[build] Building DKM input drivers...' +Build-DkmDriver (Join-Path $Root 'CODE\DKM\ps2kbd\ps2kbd.c') (Join-Path $SystemDir 'driver\input\ps2kbd.drv') + Write-Host "[build] Output: $Output" Write-Host "[build] DSK Output: $DskOutput" Write-Host "[build] Variant: $Variant"