179 lines
5.1 KiB
Bash
Executable File
179 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
BOOT_ROOT="/build/boot"
|
|
OUTPUT_DIR="/build/output"
|
|
CONFIG_DIR="/build/configs"
|
|
|
|
echo "[+] Building minimal boot initramfs..."
|
|
echo " Target: ~10-20MB embedded in kernel"
|
|
echo " Purpose: Boot + network + mount Alpine runtime"
|
|
|
|
# Clean and create boot root
|
|
rm -rf "$BOOT_ROOT"
|
|
mkdir -p "$BOOT_ROOT"
|
|
|
|
echo "[+] Installing minimal boot packages..."
|
|
|
|
# Set up APK for boot root
|
|
mkdir -p "$BOOT_ROOT/etc/apk"
|
|
cp /etc/apk/repositories "$BOOT_ROOT/etc/apk/"
|
|
|
|
# Copy APK keys
|
|
if [ -d /etc/apk/keys ]; then
|
|
mkdir -p "$BOOT_ROOT/etc/apk/keys"
|
|
cp /etc/apk/keys/* "$BOOT_ROOT/etc/apk/keys/"
|
|
fi
|
|
|
|
# Create APK database
|
|
mkdir -p "$BOOT_ROOT/lib/apk/db"
|
|
mkdir -p "$BOOT_ROOT/var/cache/apk"
|
|
|
|
# Install absolute minimal packages
|
|
echo " Installing boot packages from packages-boot.txt..."
|
|
apk --root "$BOOT_ROOT" --clean-protected --update-cache --initdb add alpine-baselayout busybox apk-tools musl
|
|
|
|
# Install additional boot packages
|
|
while read -r package; do
|
|
# Skip comments and empty lines
|
|
case "$package" in
|
|
\#*|"") continue ;;
|
|
esac
|
|
|
|
echo " Installing: $package"
|
|
if apk --root "$BOOT_ROOT" add --no-cache "$package"; then
|
|
echo " Success: $package"
|
|
else
|
|
echo " Warning: Failed to install $package"
|
|
fi
|
|
done < "$CONFIG_DIR/packages-boot.txt"
|
|
|
|
echo "[+] Installing minimal ethernet drivers..."
|
|
# Install essential ethernet firmware and drivers using our minimal script
|
|
INITRAMFS_ROOT="$BOOT_ROOT" /build/scripts/install-firmware-minimal.sh
|
|
|
|
echo "[+] Setting up boot filesystem structure..."
|
|
|
|
# Create essential directories
|
|
mkdir -p "$BOOT_ROOT"/{dev,proc,sys,mnt,tmp,var/run,var/log}
|
|
mkdir -p "$BOOT_ROOT"/{root,home,opt}
|
|
mkdir -p "$BOOT_ROOT"/mnt/{alpine,debug}
|
|
|
|
# Create device nodes
|
|
echo " Creating device nodes..."
|
|
[ ! -e "$BOOT_ROOT/dev/console" ] && mknod "$BOOT_ROOT/dev/console" c 5 1
|
|
[ ! -e "$BOOT_ROOT/dev/null" ] && mknod "$BOOT_ROOT/dev/null" c 1 3
|
|
[ ! -e "$BOOT_ROOT/dev/zero" ] && mknod "$BOOT_ROOT/dev/zero" c 1 5
|
|
|
|
# Set proper permissions
|
|
chmod 666 "$BOOT_ROOT/dev/null" "$BOOT_ROOT/dev/zero"
|
|
chmod 600 "$BOOT_ROOT/dev/console"
|
|
|
|
echo "[+] Creating boot init script..."
|
|
# Create minimal init script for mounting Alpine runtime
|
|
cat > "$BOOT_ROOT/init" << 'EOF'
|
|
#!/bin/bash
|
|
# Minimal boot init - establish network and mount Alpine runtime
|
|
|
|
echo "[BOOT] Zero-OS minimal boot starting..."
|
|
|
|
# Mount essential filesystems
|
|
mount -t proc proc /proc
|
|
mount -t sysfs sysfs /sys
|
|
mount -t devtmpfs devtmpfs /dev
|
|
|
|
# Load essential modules
|
|
echo "[BOOT] Loading ethernet drivers..."
|
|
modprobe -a e1000 e1000e igb ixgbe r8169 8139too bnx2 tg3 2>/dev/null || true
|
|
|
|
# Start eudev for hardware detection
|
|
echo "[BOOT] Starting hardware detection..."
|
|
/sbin/udevd --daemon
|
|
udevadm trigger
|
|
udevadm settle
|
|
|
|
# Network configuration
|
|
echo "[BOOT] Configuring network..."
|
|
for iface in $(ls /sys/class/net/ | grep -v lo); do
|
|
echo " Bringing up interface: $iface"
|
|
ip link set "$iface" up
|
|
# Try DHCP with timeout
|
|
timeout 30 dhcpcd "$iface" && break
|
|
done
|
|
|
|
# Mount Alpine runtime system
|
|
echo "[BOOT] Mounting Alpine runtime system..."
|
|
|
|
# Check for VirtioFS mount (development)
|
|
if [ -d /sys/fs/virtio_fs ]; then
|
|
echo " Attempting VirtioFS mount..."
|
|
mount -t virtiofs alpine-root /mnt/alpine && ALPINE_MOUNTED=true
|
|
fi
|
|
|
|
# If VirtioFS failed, try network mount (production)
|
|
if [ "$ALPINE_MOUNTED" != "true" ]; then
|
|
echo " VirtioFS not available, attempting network mount..."
|
|
# Add network mounting logic here (NFS, HTTP, etc.)
|
|
echo " Network mount not implemented yet"
|
|
fi
|
|
|
|
# Switch to Alpine runtime if mounted
|
|
if [ "$ALPINE_MOUNTED" = "true" ]; then
|
|
echo "[BOOT] Switching to Alpine runtime system..."
|
|
|
|
# Move boot mounts to Alpine
|
|
mount --move /proc /mnt/alpine/proc
|
|
mount --move /sys /mnt/alpine/sys
|
|
mount --move /dev /mnt/alpine/dev
|
|
|
|
# Switch root to Alpine
|
|
exec switch_root /mnt/alpine /sbin/zinit
|
|
else
|
|
echo "[BOOT] Failed to mount Alpine runtime - dropping to shell"
|
|
exec /bin/sh
|
|
fi
|
|
EOF
|
|
|
|
chmod +x "$BOOT_ROOT/init"
|
|
|
|
echo "[+] Setting up symlinks..."
|
|
cd "$BOOT_ROOT"
|
|
|
|
# Standard symlinks
|
|
ln -sf usr/lib lib || true
|
|
ln -sf usr/lib lib64 || true
|
|
|
|
# Fixed run symlink (not circular)
|
|
mkdir -p run
|
|
cd var
|
|
ln -sf ../run run || true
|
|
cd ..
|
|
|
|
echo "[+] Cleaning up boot initramfs..."
|
|
# Remove unnecessary files
|
|
rm -rf var/cache/apk/*
|
|
rm -rf usr/share/doc usr/share/man usr/share/info 2>/dev/null || true
|
|
|
|
# Aggressive cleanup for embedded
|
|
find . -name "*.a" -delete 2>/dev/null || true
|
|
find . -name "*.la" -delete 2>/dev/null || true
|
|
|
|
echo "[+] Creating boot initramfs archive..."
|
|
cd "$BOOT_ROOT"
|
|
|
|
# Create cpio archive
|
|
find . | cpio -H newc -o > "$OUTPUT_DIR/boot-initramfs.cpio"
|
|
|
|
if [ -f "$OUTPUT_DIR/boot-initramfs.cpio" ]; then
|
|
size=$(stat -c%s "$OUTPUT_DIR/boot-initramfs.cpio")
|
|
size_mb=$((size / 1024 / 1024))
|
|
echo "[+] Boot initramfs created: $OUTPUT_DIR/boot-initramfs.cpio (${size_mb}MB)"
|
|
else
|
|
echo "[-] Error: Failed to create boot initramfs"
|
|
exit 1
|
|
fi
|
|
|
|
echo "[+] Minimal boot initramfs build complete"
|
|
echo " Size: ${size_mb}MB (target: ~10-20MB)"
|
|
echo " Contains: Boot + network + minimal drivers"
|
|
echo " Purpose: Mount and switch to Alpine runtime" |