initramfs+kernel: path anchors, helper, and init debug hook
initramfs: anchor relative paths to PROJECT_ROOT in [bash.initramfs_validate()](scripts/lib/initramfs.sh:799) and [bash.initramfs_create_cpio()](scripts/lib/initramfs.sh:688) to avoid CWD drift. Add diagnostics logs. kernel: anchor kernel output path to PROJECT_ROOT in [bash.kernel_build_with_initramfs()](scripts/lib/kernel.sh:174) to ensure dist/vmlinuz.efi is under PROJECT_ROOT/dist. helper: add [scripts/rebuild-after-zinit.sh](scripts/rebuild-after-zinit.sh) to incrementally rebuild after zinit/modules.conf/init changes. Default: initramfs-only (recreates cpio). Flags: --with-kernel, --refresh-container-mods, --run-tests. Uses --rebuild-from=initramfs_create when rebuilding kernel. init: add early debug shell on kernel param initdebug=true; prefer /init-debug when present else spawn /bin/sh -l. See [config/init](config/init:1). modules(stage1): add USB keyboard support (HID + host controllers) in [config/modules.conf](config/modules.conf:1): usbhid, hid_generic, hid, xhci/ehci/ohci/uhci.
This commit is contained in:
29
config/init
29
config/init
@@ -24,6 +24,12 @@ mount -t devtmpfs devtmpfs /dev
|
|||||||
mkdir -p /dev/pts
|
mkdir -p /dev/pts
|
||||||
mount -t devpts devpts /dev/pts
|
mount -t devpts devpts /dev/pts
|
||||||
|
|
||||||
|
# Early debug shell if kernel parameter initdebug=true is present
|
||||||
|
if grep -qw "initdebug=true" /proc/cmdline; then
|
||||||
|
echo "[+] initdebug=true detected; starting emergency shell. Type 'exit' to continue boot."
|
||||||
|
/bin/sh -l
|
||||||
|
fi
|
||||||
|
|
||||||
echo "[+] building ram filesystem"
|
echo "[+] building ram filesystem"
|
||||||
|
|
||||||
|
|
||||||
@@ -100,19 +106,34 @@ modprobe virtio_net 2>/dev/null || true
|
|||||||
modprobe e1000 2>/dev/null || true
|
modprobe e1000 2>/dev/null || true
|
||||||
modprobe e1000e 2>/dev/null || true
|
modprobe e1000e 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "[+] loading USB keyboard support"
|
||||||
|
modprobe usbcore
|
||||||
|
modprobe ehci-hcd
|
||||||
|
modprobe xhci-hcd
|
||||||
|
modprobe usbhid
|
||||||
|
modprobe evdev
|
||||||
|
|
||||||
# Unmount init filesystems
|
# Unmount init filesystems
|
||||||
umount /proc 2>/dev/null || true
|
umount /proc 2>/dev/null || true
|
||||||
umount /sys 2>/dev/null || true
|
umount /sys 2>/dev/null || true
|
||||||
|
|
||||||
echo "[+] checking for debug files"
|
echo "[+] debug hook: initdebug=true or /init-debug"
|
||||||
if [ -e /init-debug ]; then
|
if grep -qw "initdebug=true" /proc/cmdline; then
|
||||||
echo " executing debug script..."
|
if [ -x /init-debug ]; then
|
||||||
|
echo " initdebug=true: executing /init-debug ..."
|
||||||
|
sh /init-debug
|
||||||
|
else
|
||||||
|
echo " initdebug=true: starting interactive shell (no /init-debug). Type 'exit' to continue."
|
||||||
|
/bin/sh -l
|
||||||
|
fi
|
||||||
|
elif [ -x /init-debug ]; then
|
||||||
|
echo " executing /init-debug ..."
|
||||||
sh /init-debug
|
sh /init-debug
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "[+] switching root"
|
echo "[+] switching root"
|
||||||
mkdir /root/home
|
mkdir /root/home
|
||||||
echo " exec switch_root /mnt/root /sbin/zinit init"
|
echo " exec switch_root /mnt/root /sbin/zinit init"
|
||||||
exec switch_root /mnt/root /sbin/zinit init
|
exec switch_root /mnt/root /sbin/zinit -d init
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|||||||
@@ -38,3 +38,20 @@ stage1:tun:none # TUN/TAP for networking
|
|||||||
stage1:overlay:none # OverlayFS for containers
|
stage1:overlay:none # OverlayFS for containers
|
||||||
stage1:fuse:none # OverlayFS for containers
|
stage1:fuse:none # OverlayFS for containers
|
||||||
|
|
||||||
|
# Stage 1: USB keyboard support (host controllers + HID)
|
||||||
|
stage1:xhci_pci:none
|
||||||
|
stage1:xhci_hcd:none
|
||||||
|
stage1:ehci_pci:none
|
||||||
|
stage1:ehci_hcd:none
|
||||||
|
stage1:ohci_pci:none
|
||||||
|
stage1:ohci_hcd:none
|
||||||
|
stage1:uhci_hcd:none
|
||||||
|
stage1:usbhid:none
|
||||||
|
stage1:hid_generic:none
|
||||||
|
stage1:hid:none
|
||||||
|
stage1:atkbd:none
|
||||||
|
stage1:libps2:none
|
||||||
|
stage1:i2c_smbus:none
|
||||||
|
stage1:serio:none
|
||||||
|
stage1:i8042i:none
|
||||||
|
|
||||||
|
|||||||
@@ -691,6 +691,24 @@ function initramfs_create_cpio() {
|
|||||||
local compression="${3:-$INITRAMFS_COMPRESSION}"
|
local compression="${3:-$INITRAMFS_COMPRESSION}"
|
||||||
|
|
||||||
section_header "Creating initramfs.cpio.${compression}"
|
section_header "Creating initramfs.cpio.${compression}"
|
||||||
|
|
||||||
|
# Diagnostics and path normalization (anchor relative to PROJECT_ROOT)
|
||||||
|
log_info "Create CPIO debug: input='${initramfs_dir}' PWD=$(pwd) PROJECT_ROOT=${PROJECT_ROOT:-unset}"
|
||||||
|
local _initramfs_dir_resolved
|
||||||
|
if is_absolute_path "${initramfs_dir}"; then
|
||||||
|
_initramfs_dir_resolved="${initramfs_dir}"
|
||||||
|
log_debug "Create CPIO path strategy: absolute input honored"
|
||||||
|
else
|
||||||
|
if [[ -n "${PROJECT_ROOT:-}" ]]; then
|
||||||
|
_initramfs_dir_resolved="${PROJECT_ROOT}/${initramfs_dir#./}"
|
||||||
|
log_debug "Create CPIO path strategy: relative input anchored to PROJECT_ROOT"
|
||||||
|
else
|
||||||
|
_initramfs_dir_resolved="$(pwd)/${initramfs_dir}"
|
||||||
|
log_warn "PROJECT_ROOT unset; falling back to PWD anchoring"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
log_info "Create CPIO debug: resolved initramfs_dir='${_initramfs_dir_resolved}'"
|
||||||
|
initramfs_dir="${_initramfs_dir_resolved}"
|
||||||
|
|
||||||
if [[ ! -d "$initramfs_dir" ]]; then
|
if [[ ! -d "$initramfs_dir" ]]; then
|
||||||
log_error "Initramfs directory not found: ${initramfs_dir}"
|
log_error "Initramfs directory not found: ${initramfs_dir}"
|
||||||
|
|||||||
@@ -206,15 +206,29 @@ function kernel_build_with_initramfs() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Resolve output path to absolute BEFORE cd side-effects influence relative paths
|
||||||
|
local output_abs="$output_file"
|
||||||
|
if [[ "$output_abs" != /* ]]; then
|
||||||
|
if [[ -n "${PROJECT_ROOT:-}" ]]; then
|
||||||
|
output_abs="${PROJECT_ROOT}/${output_abs#./}"
|
||||||
|
log_debug "kernel_build_with_initramfs: output path anchored to PROJECT_ROOT: ${output_abs}"
|
||||||
|
else
|
||||||
|
output_abs="$(pwd)/${output_abs}"
|
||||||
|
log_warn "kernel_build_with_initramfs: PROJECT_ROOT unset; output anchored to PWD: ${output_abs}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Copy to output location
|
# Copy to output location
|
||||||
local output_dir=$(dirname "$output_file")
|
local output_dir
|
||||||
|
output_dir=$(dirname "$output_abs")
|
||||||
safe_mkdir "$output_dir"
|
safe_mkdir "$output_dir"
|
||||||
safe_copy "$kernel_image" "$output_file"
|
safe_copy "$kernel_image" "$output_abs"
|
||||||
|
|
||||||
# Verify final kernel
|
# Verify final kernel
|
||||||
local kernel_size=$(get_file_size "$output_file")
|
local kernel_size
|
||||||
|
kernel_size=$(get_file_size "$output_abs")
|
||||||
log_info "Kernel build complete:"
|
log_info "Kernel build complete:"
|
||||||
log_info " Output file: ${output_file}"
|
log_info " Output file: ${output_abs}"
|
||||||
log_info " Kernel size: ${kernel_size}"
|
log_info " Kernel size: ${kernel_size}"
|
||||||
|
|
||||||
# Verify initramfs is embedded
|
# Verify initramfs is embedded
|
||||||
|
|||||||
116
scripts/rebuild-after-zinit.sh
Executable file
116
scripts/rebuild-after-zinit.sh
Executable file
@@ -0,0 +1,116 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Rebuild kernel (and required prior stages) after zinit config or init scripts change
|
||||||
|
# Usage:
|
||||||
|
# scripts/rebuild-after-zinit.sh # minimal rebuild of initramfs only (skip boot tests; no kernel rebuild)
|
||||||
|
# scripts/rebuild-after-zinit.sh --run-tests # include boot tests (still no kernel rebuild by default)
|
||||||
|
# scripts/rebuild-after-zinit.sh --with-kernel # also rebuild kernel (re-embed updated initramfs)
|
||||||
|
# scripts/rebuild-after-zinit.sh --refresh-container-mods # rebuild container /lib/modules if missing (kernel modules stage)
|
||||||
|
# scripts/rebuild-after-zinit.sh -- ... # pass extra args to build.sh
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
STAGES_DIR="${PROJECT_ROOT}/.build-stages"
|
||||||
|
|
||||||
|
log() { echo "[rebuild-zinit] $*"; }
|
||||||
|
|
||||||
|
run_tests=0
|
||||||
|
extra_args=()
|
||||||
|
rebuild_kernel=0
|
||||||
|
refresh_container_mods=0
|
||||||
|
|
||||||
|
# Parse flags; pass through any remaining args to build.sh after --
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--run-tests)
|
||||||
|
run_tests=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--with-kernel)
|
||||||
|
rebuild_kernel=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--refresh-container-mods)
|
||||||
|
refresh_container_mods=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
extra_args=("$@")
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Pass unknown args through to build.sh
|
||||||
|
extra_args+=("$1")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
log "PROJECT_ROOT=${PROJECT_ROOT}"
|
||||||
|
log "STAGES_DIR=${STAGES_DIR}"
|
||||||
|
|
||||||
|
# Minimal set of stages to clear when zinit changes:
|
||||||
|
# - zinit_setup: recopy zinit YAML and init scripts into initramfs
|
||||||
|
# - validation: re-check initramfs contents
|
||||||
|
# - initramfs_create: recreate archive including updated zinit files
|
||||||
|
# - initramfs_test: re-test archive
|
||||||
|
# - kernel_build: re-embed updated initramfs into kernel
|
||||||
|
# - boot_tests: optional, depends on --run-tests
|
||||||
|
stages_to_clear=(
|
||||||
|
# Ensure new/changed module selections in [config/modules.conf](config/modules.conf)
|
||||||
|
# are re-resolved and copied into the initramfs:
|
||||||
|
"modules_setup"
|
||||||
|
"modules_copy"
|
||||||
|
|
||||||
|
# Re-copy /init into the initramfs root from [config/init](config/init)
|
||||||
|
"init_script"
|
||||||
|
|
||||||
|
# Ensure zinit YAML/init script changes are reapplied:
|
||||||
|
"zinit_setup"
|
||||||
|
|
||||||
|
# Re-validate and recreate archive (no kernel rebuild by default):
|
||||||
|
"validation"
|
||||||
|
"initramfs_create"
|
||||||
|
"initramfs_test"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Optionally rebuild container modules if requested (fresh container scenario)
|
||||||
|
if [[ "$refresh_container_mods" -eq 1 ]]; then
|
||||||
|
stages_to_clear=("kernel_modules" "${stages_to_clear[@]}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Optionally rebuild kernel (re-embed updated initramfs)
|
||||||
|
if [[ "$rebuild_kernel" -eq 1 ]]; then
|
||||||
|
stages_to_clear+=("kernel_build")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove completion markers to force incremental rebuild of those stages
|
||||||
|
for s in "${stages_to_clear[@]}"; do
|
||||||
|
marker="${STAGES_DIR}/${s}.done"
|
||||||
|
if [[ -f "$marker" ]]; then
|
||||||
|
log "Removing stage marker: ${marker}"
|
||||||
|
rm -f "$marker"
|
||||||
|
else
|
||||||
|
log "Marker not present (already pending): ${s}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Build
|
||||||
|
log "Starting incremental rebuild (zinit changes)"
|
||||||
|
# If we plan to rebuild the kernel, force the pipeline to run from initramfs_create
|
||||||
|
# so the cpio archive is recreated before kernel_build (ignoring prior .done markers).
|
||||||
|
build_from_args=()
|
||||||
|
if [[ "$rebuild_kernel" -eq 1 ]]; then
|
||||||
|
build_from_args=(--rebuild-from=initramfs_create)
|
||||||
|
log "Rebuild-from: initramfs_create (guarantee cpio is recreated before kernel_build)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$run_tests" -eq 1 ]]; then
|
||||||
|
log "Including boot tests"
|
||||||
|
DEBUG=1 "${PROJECT_ROOT}/scripts/build.sh" "${build_from_args[@]}" "${extra_args[@]}"
|
||||||
|
else
|
||||||
|
log "Skipping boot tests (use --run-tests to include)"
|
||||||
|
DEBUG=1 "${PROJECT_ROOT}/scripts/build.sh" --skip-tests "${build_from_args[@]}" "${extra_args[@]}"
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user