#!/bin/sh # Blancco PXE Loader - init script for custom initramfs # Boot chain: iPXE -> GRUB EFI -> Ubuntu kernel + this initramfs -> switch_root to Blancco # # Blancco's own kernel freezes on Dell Precision towers during PXE boot. # Workaround: boot Ubuntu kernel, download Blancco rootfs (squashfs), mount # overlay filesystem, and switch_root into Blancco's userspace. export PATH=/bin:/sbin echo "" echo "============================================" echo " Blancco PXE loader" echo "============================================" echo "" mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t devtmpfs devtmpfs /dev 2>/dev/null mkdir -p /tmp /run echo "[1/4] Loading NIC drivers..." echo " Kernel: $(uname -r)" echo " Interfaces before driver load: $(ls /sys/class/net/ 2>/dev/null)" # Dependency modules first. insmod does not resolve deps; main NIC # drivers like igb need dca + i2c-algo-bit, atlantic needs macsec, # some Intel drivers need libeth/libie. Load helpers first so the # main driver module has its required symbols available. for mod in /lib/modules/libeth.ko /lib/modules/libie*.ko /lib/modules/dca.ko \ /lib/modules/i2c-algo-bit.ko /lib/modules/macsec.ko \ /lib/modules/mii.ko /lib/modules/ssb.ko /lib/modules/libphy.ko \ /lib/modules/mdio*.ko /lib/modules/phy*.ko /lib/modules/ptp*.ko; do [ -f "$mod" ] || continue insmod "$mod" 2>&1 | grep -v '^$' | head -1 || true done # Main NIC drivers (everything else in /lib/modules/ that is not a helper # or the overlay/squashfs modules). Errors are now VISIBLE so if a # driver fails to load we can see why. for mod in /lib/modules/*.ko; do base=$(basename "$mod") case "$base" in libeth.ko|libie*.ko|dca.ko|i2c-algo-bit.ko|macsec.ko|mii.ko|ssb.ko|libphy.ko|overlay.ko|squashfs.ko|mdio*.ko|phy*.ko|ptp*.ko) continue ;; esac echo " insmod $base" insmod "$mod" 2>&1 | head -1 || true done sleep 5 echo " Interfaces after driver load: $(ls /sys/class/net/ 2>/dev/null)" echo " Kernel messages mentioning NIC driver activity:" dmesg 2>/dev/null | grep -iE "eth|igc|igb|bnxt|tg3|r8169|atlantic|e1000|ixgbe|i40e|eno|ens|enp" | tail -20 echo " Waiting for network interface..." IFACE="" COUNT=0 while [ $COUNT -lt 60 ]; do for i in /sys/class/net/*; do ifname="${i##*/}" if [ "$ifname" != "lo" ] && [ -d "$i" ]; then IFACE=$ifname break 2 fi done COUNT=$((COUNT + 1)) sleep 1 echo -n "." done echo "" if [ -z "$IFACE" ]; then echo "" echo "ERROR: No network interface found after 60s." echo " /sys/class/net/: $(ls /sys/class/net/ 2>/dev/null)" echo " Last 40 lines of dmesg (look for probe failures):" dmesg 2>/dev/null | tail -40 echo "" echo " Dropping to busybox shell for manual debug. reboot with 'reboot -f'." exec sh fi echo " Interface: $IFACE" ip link set $IFACE up sleep 2 SERVER=10.9.100.1 ifconfig $IFACE 10.9.100.250 netmask 255.255.255.0 up sleep 1 echo " IP: 10.9.100.250" echo "[2/4] Downloading Blancco rootfs (666MB)..." wget -O /tmp/airootfs.sfs http://$SERVER/blancco/arch/x86_64/airootfs.sfs 2>&1 if [ ! -s /tmp/airootfs.sfs ]; then echo "ERROR: Failed to download rootfs!" exec sh fi echo " OK ($(wc -c < /tmp/airootfs.sfs) bytes)" echo "[3/4] Mounting rootfs..." mkdir -p /run/lower /run/upper /run/work /run/newroot losetup /dev/loop0 /tmp/airootfs.sfs mount -t squashfs -o ro /dev/loop0 /run/lower if [ $? -ne 0 ]; then echo "ERROR: squashfs mount failed!" exec sh fi insmod /lib/modules/overlay.ko 2>/dev/null mount -t tmpfs -o size=50% tmpfs /run/upper mkdir -p /run/upper/upper /run/upper/work mount -t overlay overlay -o lowerdir=/run/lower,upperdir=/run/upper/upper,workdir=/run/upper/work /run/newroot if [ $? -ne 0 ]; then echo "ERROR: overlay mount failed!" exec sh fi echo "[4/5] Installing kernel modules (132MB)..." wget -O /tmp/kmod.tar.gz http://$SERVER/blancco/kmod.tar.gz 2>&1 if [ -s /tmp/kmod.tar.gz ]; then cd /run/newroot gunzip -c /tmp/kmod.tar.gz | tar xf - rm -f /tmp/kmod.tar.gz cd / echo " OK" else echo " WARNING: Failed to download kernel modules" fi echo "[5/6] Switching root to Blancco..." mkdir -p /run/newroot/run /run/newroot/proc /run/newroot/sys /run/newroot/dev /run/newroot/tmp echo "[6/6] Downloading Blancco config..." wget -O /run/newroot/albus/config.xml http://$SERVER/blancco/config-clean.xml 2>&1 wget -O /run/newroot/albus/preferences.xml http://$SERVER/blancco/preferences.xml 2>&1 if [ -s /run/newroot/albus/config.xml ]; then echo " config.xml: $(wc -c < /run/newroot/albus/config.xml) bytes" else echo " WARNING: Failed to download config.xml" fi if [ -s /run/newroot/albus/preferences.xml ]; then cp -f /run/newroot/albus/preferences.xml /run/newroot/albus/preferences.save echo " preferences.xml: $(wc -c < /run/newroot/albus/preferences.xml) bytes" else echo " WARNING: Failed to download preferences.xml" fi # Pre-configure X.org to use modesetting driver (generic KMS, works with all GPUs) mkdir -p /run/newroot/etc/X11/xorg.conf.d echo " X.org: forcing modesetting driver" cat > /run/newroot/etc/X11/xorg.conf.d/20-failsafeDriver.conf << 'XEOF' Section "Device" Identifier "Failsafe Video Device" Driver "modesetting" EndSection XEOF # Enable SSH for remote debugging echo " Enabling SSH (root:blancco)..." if [ -f /run/newroot/etc/ssh/sshd_config ]; then sed 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /run/newroot/etc/ssh/sshd_config > /run/newroot/etc/ssh/sshd_config.new || true mv /run/newroot/etc/ssh/sshd_config.new /run/newroot/etc/ssh/sshd_config || true fi cat > /run/newroot/etc/rc.local << 'RCEOF' #!/bin/bash echo 'root:blancco' | chpasswd ssh-keygen -A 2>/dev/null /usr/bin/sshd 2>/dev/null RCEOF chmod +x /run/newroot/etc/rc.local cat > /run/newroot/etc/systemd/system/pxe-debug.service << 'SVCEOF' [Unit] Description=PXE Debug SSH After=network.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/etc/rc.local [Install] WantedBy=multi-user.target SVCEOF ln -sf /etc/systemd/system/pxe-debug.service /run/newroot/etc/systemd/system/multi-user.target.wants/pxe-debug.service 2>/dev/null mount --move /proc /run/newroot/proc mount --move /sys /run/newroot/sys mount --move /dev /run/newroot/dev echo " Starting Blancco..." exec switch_root /run/newroot /sbin/init