initramfs+modules: robust copy aliasing, curated stage1 + PHYs, firmware policy via firmware.conf, runtime readiness, build ID; docs sync
Some checks failed
Build Zero OS Initramfs / build (push) Has been cancelled
Build Zero OS Initramfs / test-matrix (qemu, basic) (push) Has been cancelled
Build Zero OS Initramfs / test-matrix (qemu, serial) (push) Has been cancelled

Summary of changes (with references):\n\nModules + PHY coverage\n- Curated and normalized stage1 list in [config.modules.conf](config/modules.conf:1):\n  - Boot-critical storage, core virtio, common NICs (Intel/Realtek/Broadcom), overlay/fuse, USB HCD/HID.\n  - Added PHY drivers required by NIC MACs:\n    * realtek (for r8169, etc.)\n    * broadcom families: broadcom, bcm7xxx, bcm87xx, bcm_phy_lib, bcm_phy_ptp\n- Robust underscore↔hyphen aliasing during copy so e.g. xhci_pci → xhci-pci.ko, hid_generic → hid-generic.ko:\n  - [bash.initramfs_copy_resolved_modules()](scripts/lib/initramfs.sh:990)\n\nFirmware policy and coverage\n- Firmware selection now authoritative via [config/firmware.conf](config/firmware.conf:1); ignore modules.conf firmware hints:\n  - [bash.initramfs_setup_modules()](scripts/lib/initramfs.sh:229)\n  - Count from firmware.conf for reporting; remove stale required-firmware.list.\n- Expanded NIC firmware set (bnx2, bnx2x, tigon, intel, realtek, rtl_nic, qlogic, e100) in [config.firmware.conf](config/firmware.conf:1).\n- Installer enforces firmware.conf source-of-truth in [bash.alpine_install_firmware()](scripts/lib/alpine.sh:392).\n\nEarly input & build freshness\n- Write a runtime build stamp to /etc/zero-os-build-id for embedded initramfs verification:\n  - [bash.initramfs_finalize_customization()](scripts/lib/initramfs.sh:568)\n- Minor init refinements in [config.init](config/init:1) (ensures /home, consistent depmod path).\n\nRebuild helper improvements\n- [scripts/rebuild-after-zinit.sh](scripts/rebuild-after-zinit.sh:1):\n  - Added --verify-only; container-aware execution; selective marker clears only.\n  - Prints stage status before/after; avoids --rebuild-from; resolves full kernel version for diagnostics.\n\nRemote flist readiness + zinit\n- Init scripts now probe BASE_URL readiness and accept FLISTS_BASE_URL/FLIST_BASE_URL; firmware target is /lib/firmware:\n  - [sh.firmware.sh](config/zinit/init/firmware.sh:1)\n  - [sh.modules.sh](config/zinit/init/modules.sh:1)\n\nContainer, docs, and utilities\n- Stream container build logs by calling runtime build directly in [bash.docker_build_container()](scripts/lib/docker.sh:56).\n- Docs updated to reflect firmware policy, runtime readiness, rebuild helper, early input, and GRUB USB:\n  - [docs.NOTES.md](docs/NOTES.md)\n  - [docs.PROMPT.md](docs/PROMPT.md)\n  - [docs.review-rfs-integration.md](docs/review-rfs-integration.md)\n- Added GRUB USB creator (referenced in docs): [scripts/make-grub-usb.sh](scripts/make-grub-usb.sh)\n\nCleanup\n- Removed legacy/duplicated config trees under configs/ and config/zinit.old/.\n- Minor newline and ignore fixes: [.gitignore](.gitignore:1)\n\nNet effect\n- Runtime now has correct USB HCDs/HID-generic and NIC+PHY coverage (Realtek/Broadcom), with matching firmware installed in initramfs.\n- Rebuild workflow is minimal and host/container-aware; docs are aligned with implemented behavior.\n
This commit is contained in:
2025-09-23 14:03:01 +02:00
parent 2fba2bd4cd
commit ad0a06e267
87 changed files with 833 additions and 17307 deletions

256
scripts/make-grub-usb.sh Normal file
View File

@@ -0,0 +1,256 @@
#!/usr/bin/env bash
# Create a GRUB USB disk that boots on both BIOS (legacy) and UEFI.
# It copies kernel (vmlinuz) and initramfs, installs GRUB for i386-pc and x86_64-efi,
# and writes a minimal grub.cfg with optional kernel parameters.
#
# DANGEROUS: This script will repartition and format the target device (e.g., /dev/sdX).
#
# Usage:
# sudo scripts/make-grub-usb.sh /dev/sdX \
# --kernel dist/vmlinuz.efi \
# --initrd dist/initramfs.cpio.xz \
# --kparams "console=ttyS0 initdebug=true" \
# --label ZOSBOOT \
# --no-confirm
#
# Defaults (resolved relative to repo root):
# --kernel dist/vmlinuz.efi
# --initrd dist/initramfs.cpio.xz
# --label ZOS
# --kparams "" (none)
#
# Requirements on host:
# - grub-install (supports --target=i386-pc and --target=x86_64-efi)
# - parted, sfdisk (optional), dosfstools (mkfs.vfat), util-linux (lsblk, partprobe)
# - run as root
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
DEVICE="${1:-}"
shift || true
KERNEL="${PROJECT_ROOT}/dist/vmlinuz.efi"
# Default: no separate initrd because initramfs is embedded in kernel. Enable with --with-initrd or --initrd.
INITRD=""
KPARAMS=""
LABEL="ZOS"
NO_CONFIRM=0
ESP_SIZE_MB=512
# Request including separate initrd
WANT_INITRD=0
error() { echo "[ERROR] $*" >&2; }
info() { echo "[INFO] $*"; }
warn() { echo "[WARN] $*"; }
die() { error "$*"; exit 1; }
require_root() {
[[ "$EUID" -eq 0 ]] || die "This script must be run as root."
}
command_exists() { command -v "$1" &>/dev/null; }
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
--kernel)
KERNEL="$(realpath -m "${2:-}")"; shift 2 ;;
--initrd)
INITRD="$(realpath -m "${2:-}")"; shift 2 ;;
--with-initrd)
WANT_INITRD=1; shift ;;
--kparams)
KPARAMS="${2:-}"; shift 2 ;;
--label)
LABEL="${2:-ZOS}"; shift 2 ;;
--no-confirm)
NO_CONFIRM=1; shift ;;
--esp-size-mb)
ESP_SIZE_MB="${2:-512}"; shift 2 ;;
-*)
die "Unknown option: $1" ;;
*)
die "Unexpected argument: $1" ;;
esac
done
}
confirm_dangerous() {
info "About to wipe and repartition device: ${DEVICE}"
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT "${DEVICE}"
if [[ $NO_CONFIRM -eq 1 ]]; then
info "--no-confirm provided; proceeding without interactive confirmation"
return
fi
echo
read -r -p "Type the DEVICE path to CONFIRM (e.g., ${DEVICE}) or 'abort' to cancel: " ans
[[ "$ans" == "$DEVICE" ]] || die "Confirmation mismatch or aborted."
}
check_prereqs() {
command_exists parted || die "parted not found"
command_exists mkfs.vfat || die "mkfs.vfat (dosfstools) not found"
command_exists grub-install || die "grub-install not found"
command_exists lsblk || die "lsblk not found"
command_exists partprobe || die "partprobe not found"
}
resolve_defaults() {
[[ -b "$DEVICE" ]] || die "Device not found or not a block device: ${DEVICE}"
[[ -f "$KERNEL" ]] || die "Kernel file not found: ${KERNEL}"
if [[ $WANT_INITRD -eq 1 ]]; then
# If user asked for separate initrd but none specified, use default path
if [[ -z "${INITRD}" ]]; then
INITRD="${PROJECT_ROOT}/dist/initramfs.cpio.xz"
fi
[[ -f "$INITRD" ]] || die "Requested --with-initrd but initramfs not found: ${INITRD}"
else
# By default, no separate initrd (initramfs is embedded in kernel)
INITRD=""
fi
}
umount_partitions() {
info "Unmounting any mounted partitions of ${DEVICE}"
local kids
kids="$(lsblk -nr -o NAME "${DEVICE}" | tail -n +2 || true)"
if [[ -n "${kids}" ]]; then
while read -r name; do
[[ -z "$name" ]] && continue
local path="/dev/${name}"
if mountpoint -q -- "/dev/${name}" 2>/dev/null; then
umount -f "/dev/${name}" || true
fi
# also try mounts by path
local mp
mp="$(lsblk -nr -o MOUNTPOINT "$path" || true)"
if [[ -n "$mp" ]]; then
for m in $mp; do
[[ -n "$m" ]] && umount -f "$m" || true
done
fi
done <<< "${kids}"
fi
}
partition_device_gpt() {
info "Creating GPT with BIOS boot + ESP on ${DEVICE}"
# Create a new GPT
parted -s "${DEVICE}" mklabel gpt
# Create BIOS boot partition 1MiB..3MiB
parted -s "${DEVICE}" mkpart biosgrub 1MiB 3MiB
parted -s "${DEVICE}" set 1 bios_grub on
# Create ESP (FAT32) from 3MiB to 3MiB + ESP_SIZE_MB
local esp_end="$((3 + ESP_SIZE_MB))MiB"
parted -s "${DEVICE}" mkpart esp fat32 3MiB "${esp_end}"
parted -s "${DEVICE}" set 2 esp on
# Inform kernel
partprobe "${DEVICE}"
sleep 1
}
format_esp() {
local part="${DEVICE}2"
[[ -b "$part" ]] || die "ESP partition not found: ${part}"
info "Formatting ESP ${part} as FAT32 (label=${LABEL})"
mkfs.vfat -F32 -n "${LABEL}" "$part"
}
mount_esp() {
ESP_MNT="$(mktemp -d)"
info "Mounting ESP at ${ESP_MNT}"
mount "${DEVICE}2" "${ESP_MNT}"
}
install_grub() {
info "Installing GRUB (BIOS i386-pc) to ${DEVICE}"
grub-install --target=i386-pc --boot-directory="${ESP_MNT}/boot" --recheck "${DEVICE}"
info "Installing GRUB (UEFI x86_64-efi) to ESP"
mkdir -p "${ESP_MNT}/EFI/BOOT"
grub-install --target=x86_64-efi --efi-directory="${ESP_MNT}" --boot-directory="${ESP_MNT}/boot" --removable --recheck
}
copy_kernel_initrd() {
mkdir -p "${ESP_MNT}/boot"
info "Copying kernel to ESP /boot/vmlinuz"
cp -f "${KERNEL}" "${ESP_MNT}/boot/vmlinuz"
if [[ -n "${INITRD}" ]]; then
info "Copying initramfs to ESP /boot/initramfs.cpio.xz"
cp -f "${INITRD}" "${ESP_MNT}/boot/initramfs.cpio.xz"
fi
}
write_grub_cfg() {
local cfg="${ESP_MNT}/boot/grub/grub.cfg"
info "Writing GRUB config: ${cfg}"
mkdir -p "$(dirname "$cfg")"
cat > "$cfg" <<'EOF'
set default=0
set timeout=3
if [ "${grub_platform}" = "efi" ]; then
set gfxpayload=keep
fi
menuentry "Zero-OS" {
linux /boot/vmlinuz __KPARAMS__
__INITRD_LINE__
}
EOF
local initrd_line=""
if [[ -n "${INITRD}" ]]; then
initrd_line=" initrd /boot/initramfs.cpio.xz"
fi
# Substitute placeholders
sed -i \
-e "s|__KPARAMS__|${KPARAMS}|g" \
-e "s|__INITRD_LINE__|${initrd_line}|g" \
"$cfg"
# For removable media on UEFI, ensure fallback bootloader path exists
if [[ -f "/usr/lib/grub/x86_64-efi/monolithic/grubx64.efi" ]]; then
cp -f "/usr/lib/grub/x86_64-efi/monolithic/grubx64.efi" "${ESP_MNT}/EFI/BOOT/BOOTX64.EFI" || true
elif [[ -f "${ESP_MNT}/EFI/BOOT/grubx64.efi" ]]; then
cp -f "${ESP_MNT}/EFI/BOOT/grubx64.efi" "${ESP_MNT}/EFI/BOOT/BOOTX64.EFI" || true
fi
}
cleanup() {
set +e
if mountpoint -q "${ESP_MNT}" 2>/dev/null; then
info "Unmounting ESP ${ESP_MNT}"
umount "${ESP_MNT}"
fi
[[ -n "${ESP_MNT:-}" ]] && rmdir "${ESP_MNT}" 2>/dev/null || true
}
main() {
require_root
[[ -n "${DEVICE}" ]] || die "Usage: $0 /dev/sdX [--kernel path] [--initrd path] [--kparams \"...\"] [--label ZOS] [--no-confirm]"
parse_args "$@"
resolve_defaults
check_prereqs
confirm_dangerous
trap cleanup EXIT INT TERM
umount_partitions
partition_device_gpt
format_esp
mount_esp
install_grub
copy_kernel_initrd
write_grub_cfg
info "Done. You can now boot from the USB on BIOS and UEFI systems."
}
main "$@"