#!/bin/bash set -e INITRAMFS_ROOT="/build/initramfs" # Determine which package list to use if [ "$1" = "minimal" ] || [ "$MINIMAL_MODE" = "true" ] || [ -f "/build/configs/packages-minimal.txt" -a ! -f "/build/configs/packages.txt" ]; then PACKAGES_FILE="/build/configs/packages-minimal.txt" MINIMAL_MODE=true echo "[+] Creating MINIMAL initramfs root directory (embedded cpio)..." else PACKAGES_FILE="/build/configs/packages.txt" MINIMAL_MODE=false echo "[+] Creating FULL initramfs root directory..." fi rm -rf "$INITRAMFS_ROOT" mkdir -p "$INITRAMFS_ROOT" echo "[+] Setting up Alpine repositories..." echo "[DEBUG] Checking APK setup..." echo "[DEBUG] Host repositories: $(cat /etc/apk/repositories | grep -v '^#' | wc -l) active repos" echo "[DEBUG] Host APK keys: $(ls -la /etc/apk/keys 2>/dev/null | wc -l) keys" echo "[DEBUG] Network connectivity to Alpine repos..." apk_test=$(apk update --quiet 2>&1 && echo 'OK' || echo 'FAILED') echo "[DEBUG] APK repository access: $apk_test" # Create the repository configuration and copy APK keys mkdir -p "$INITRAMFS_ROOT/etc/apk" cp /etc/apk/repositories "$INITRAMFS_ROOT/etc/apk/" # Copy APK keys to avoid UNTRUSTED signature warnings if [ -d /etc/apk/keys ]; then mkdir -p "$INITRAMFS_ROOT/etc/apk/keys" cp /etc/apk/keys/* "$INITRAMFS_ROOT/etc/apk/keys/" fi echo "[+] Installing Alpine base system..." # Create APK database directory and initialize mkdir -p "$INITRAMFS_ROOT/lib/apk/db" mkdir -p "$INITRAMFS_ROOT/var/cache/apk" # Initialize the database first with --clean-protected for new root apk --root "$INITRAMFS_ROOT" --clean-protected --update-cache --initdb add alpine-baselayout busybox apk-tools musl echo "[+] Installing Zero-OS packages..." while read -r package; do # Skip comments and empty lines case "$package" in \#*|"") continue ;; esac echo " Installing: $package" if apk --root "$INITRAMFS_ROOT" add --no-cache "$package"; then echo "[DEBUG] Successfully installed: $package" else echo " Warning: Failed to install $package (continuing)" echo "[DEBUG] Package installation failed: $package - check if package exists in repos" fi done < "$PACKAGES_FILE" # For minimal mode, install selective firmware instead of full linux-firmware package if [ "$MINIMAL_MODE" = "true" ]; then echo "[+] Installing minimal firmware (essential network drivers only)..." /build/scripts/install-firmware-minimal.sh else echo "[+] Full mode: linux-firmware package already installed" fi echo "[+] Setting up initramfs filesystem structure..." # Create essential directories mkdir -p "$INITRAMFS_ROOT"/{dev,proc,sys,mnt,tmp,var/run,var/log,var/lock} mkdir -p "$INITRAMFS_ROOT"/{root,home,opt} mkdir -p "$INITRAMFS_ROOT"/mnt/root mkdir -p "$INITRAMFS_ROOT"/var/cache/containers # Create device nodes (minimal set) - check if they exist first echo " Creating device nodes..." [ ! -e "$INITRAMFS_ROOT/dev/console" ] && mknod "$INITRAMFS_ROOT/dev/console" c 5 1 [ ! -e "$INITRAMFS_ROOT/dev/null" ] && mknod "$INITRAMFS_ROOT/dev/null" c 1 3 [ ! -e "$INITRAMFS_ROOT/dev/zero" ] && mknod "$INITRAMFS_ROOT/dev/zero" c 1 5 [ ! -e "$INITRAMFS_ROOT/dev/random" ] && mknod "$INITRAMFS_ROOT/dev/random" c 1 8 [ ! -e "$INITRAMFS_ROOT/dev/urandom" ] && mknod "$INITRAMFS_ROOT/dev/urandom" c 1 9 # Set proper permissions chmod 666 "$INITRAMFS_ROOT/dev/null" "$INITRAMFS_ROOT/dev/zero" chmod 600 "$INITRAMFS_ROOT/dev/console" chmod 644 "$INITRAMFS_ROOT/dev/random" "$INITRAMFS_ROOT/dev/urandom" # Create symlinks (similar to current system) echo " Creating symlinks..." cd "$INITRAMFS_ROOT" ln -sf usr/lib lib || true ln -sf usr/lib lib64 || true ln -sf var/run run || true # Ensure minimal login logs touch "$INITRAMFS_ROOT"/var/log/lastlog touch "$INITRAMFS_ROOT"/var/log/wtmp # Legacy mtab symlink cd "$INITRAMFS_ROOT/etc" ln -sf /proc/mounts mtab || true echo "[+] Cleaning up unnecessary files..." cd "$INITRAMFS_ROOT" # Remove package cache and docs rm -rf var/cache/apk/* rm -rf usr/share/doc rm -rf usr/share/man rm -rf usr/share/info rm -rf usr/share/locale rm -rf usr/include rm -rf usr/lib/pkgconfig # Remove development files rm -rf lib/*.a usr/lib/*.a rm -rf lib/*.la usr/lib/*.la # Aggressive cleanup for minimal mode if [ "$MINIMAL_MODE" = "true" ]; then echo " Applying aggressive size optimizations for embedded cpio..." # Remove ALL documentation and help files rm -rf usr/share/doc usr/share/man usr/share/info rm -rf usr/share/help usr/share/gtk-doc usr/share/licenses rm -rf usr/share/LICENSES usr/share/COPYING* # Remove ALL locale and internationalization rm -rf usr/share/locale usr/share/i18n rm -rf usr/lib/locale usr/lib/gconv # Remove timezone data (embedded systems often use UTC) rm -rf usr/share/zoneinfo/* 2>/dev/null || true # Remove terminfo except bare essentials (vt100, linux, xterm) rm -rf usr/share/terminfo/[b-df-km-uw-z]* 2>/dev/null || true rm -rf usr/share/terminfo/[A-Z]* 2>/dev/null || true rm -rf usr/share/terminfo/1 usr/share/terminfo/2 usr/share/terminfo/3 2>/dev/null || true # Remove graphics/desktop files (embedded has no GUI) rm -rf usr/share/pixmaps usr/share/icons usr/share/applications rm -rf usr/share/mime usr/share/desktop-directories # Remove development headers and static libraries rm -rf usr/include usr/lib/pkgconfig usr/share/pkgconfig rm -rf lib/*.a usr/lib/*.a lib/*.la usr/lib/*.la # Remove Python cache and compiled modules rm -rf usr/lib/python*/site-packages/__pycache__ rm -rf usr/lib/python*/__pycache__ usr/lib/python*/test rm -rf usr/lib/python*/tkinter usr/lib/python*/turtle* find usr/lib/python* -name "*.pyc" -delete 2>/dev/null || true find usr/lib/python* -name "*.pyo" -delete 2>/dev/null || true # Remove unnecessary logs, cache, and temporary files rm -rf var/log/* var/cache/* tmp/* var/tmp/* rm -rf var/lib/apk/db/installed var/lib/apk/db/lock rm -rf etc/apk/cache/* 2>/dev/null || true # Note: Keep kernel modules - they were installed by install-firmware-minimal.sh # Only remove unnecessary kernel module development files if they exist find lib/modules -name "*.mod" -delete 2>/dev/null || true find lib/modules -name "build" -type l -delete 2>/dev/null || true find lib/modules -name "source" -type l -delete 2>/dev/null || true # Strip binaries aggressively to reduce size echo " Stripping binaries..." find . -type f -perm -111 -exec strip --strip-unneeded {} \; 2>/dev/null || true find . -name "*.so*" -exec strip --strip-unneeded {} \; 2>/dev/null || true # Remove backup files and editor artifacts find . -name "*~" -delete 2>/dev/null || true find . -name "*.orig" -delete 2>/dev/null || true find . -name "*.rej" -delete 2>/dev/null || true # Show final firmware size echo " Minimal firmware size: $(du -sh lib/firmware 2>/dev/null | cut -f1 || echo 'N/A')" echo " Total size after aggressive cleanup: $(du -sh . | cut -f1)" fi echo "[+] Setting up Alpine-specific configurations..." # Ensure terminfo is available (needed for various tools) if [ -d /usr/share/terminfo ]; then cp -r /usr/share/terminfo "$INITRAMFS_ROOT/usr/share/" || true fi # Copy timezone data if [ -d /usr/share/zoneinfo ]; then mkdir -p "$INITRAMFS_ROOT/usr/share" cp -r /usr/share/zoneinfo "$INITRAMFS_ROOT/usr/share/" || true fi echo "[+] Alpine packages installed successfully" echo " Initramfs root: $INITRAMFS_ROOT" # Show size if command -v du >/dev/null; then size=$(du -sh "$INITRAMFS_ROOT" | cut -f1) echo " Size: $size" fi