#!/bin/bash # ============================================================================== # SCRIPT: setup_host_build_env.sh # PURPOSE: Prepares a Void Linux host environment for cross-architecture ISO builds. # # This script automates several setup steps required on the host machine # when building ISO images for architectures different from the host (e.g., # building aarch64 or i686 ISOs on an x86_64 host). # # What this script does: # 1. Updates the host's package list. # 2. Installs necessary 32-bit libraries (like lzo, libgcc, readline) on the # x86_64 host. These are required if you execute 32-bit tools (like mksquashfs # or xorriso from bootstrap environments) directly on the host system. # NOTE: If you configure your build script to run these tools *inside* # the target chroot environment using 'chroot' or 'xbps-uchroot', these # 32-bit host libraries might not be strictly necessary for *that specific* # reason, but are often needed by other host tools. # 3. Installs QEMU user mode emulators, including the one for aarch64. # 4. Ensures the 'binfmt_misc' kernel module is loaded and its filesystem is # mounted. This kernel feature allows executing binaries for foreign # architectures using emulators like QEMU. # 5. Registers the installed QEMU user emulators with the kernel's binfmt_misc # interface, enabling the execution of foreign binaries (like aarch64 # executables) via QEMU emulation when run in a chroot or similar environment. # # PREREQUISITES: # - A Void Linux host system. # - An active internet connection to download packages. # - sudo privileges to install packages and configure system settings. # # USAGE: # 1. Save this code to a file (e.g., setup_host_build_env.sh). # 2. Make the file executable: chmod +x setup_host_build_env.sh # 3. Run the script with sudo: sudo ./setup_host_build_env.sh # # IMPORTANT NOTE: # This script ONLY sets up the HOST environment. It DOES NOT modify your # iso_builder.py script. You STILL NEED to modify your iso_builder.py script # to: # - Execute cross-architecture commands (like xbps-install for bootstrap, # mksquashfs, xorriso) *inside* the target rootfs or bootstrap environment # using 'sudo chroot /path/to/target/rootfs ' or 'xbps-uchroot'. # - Ensure the correct repository URLs for the target architecture are used # in your xbps-install commands within the script. # ============================================================================== # Exit immediately if a command exits with a non-zero status. set -e # Check if running as root if [ "$EUID" -ne 0 ]; then echo "Error: Please run this script with sudo." exit 1 fi echo "=> Updating host package list..." xbps-install -S -y # Install 32-bit libraries needed for i686 tools executed on the host # These might be needed if you don't run mksquashfs/xorriso etc. in a chroot/uchroot echo "=> Installing 32-bit libraries for i686 execution on the host (if needed)..." xbps-install -y lzo-32bit libgcc-32bit readline-32bit || { echo "Warning: Failed to install one or more 32-bit packages. Continuing." # Don't exit here, as QEMU packages are still required for aarch64 etc. } # Install QEMU user mode emulators echo "=> Installing QEMU user mode emulators (including aarch64)..." # Install the qemu-user-static dummy package, which depends on architecture-specific ones. # Explicitly installing qemu-user-aarch64 for clarity, though dependency might cover it. xbps-install -y qemu-user-static qemu-user-aarch64 echo "=> Ensuring binfmt_misc kernel module is loaded and filesystem is mounted..." # Load module if not loaded if ! lsmod | grep -q binfmt_misc; then echo "Loading binfmt_misc kernel module..." modprobe binfmt_misc sleep 1 fi # Mount filesystem if not mounted if ! mountpoint -q /proc/sys/fs/binfmt_misc; then echo "Mounting binfmt_misc filesystem..." mount -t binfmt_misc none /proc/sys/fs/binfmt_misc sleep 1 fi # Verificar se o diretório está acessível após tentar carregar/montar if [ ! -d "/proc/sys/fs/binfmt_misc" ]; then echo "ERRO FATAL: O diretório /proc/sys/fs/binfmt_misc não existe ou não está acessível." echo "A configuração do binfmt_misc falhou. Não é possível continuar com a emulação." exit 1 fi echo "=> Registering QEMU user binfmts from /usr/share/binfmts/ using echo to register..." # Register all qemu binfmts found in /usr/share/binfmts/ for binfmt_file in /usr/share/binfmts/qemu-*; do if [ -f "$binfmt_file" ]; then # Get the name (e.g., qemu-aarch64) binfmt_name=$(basename "$binfmt_file") # Path in /proc where it would be registered proc_binfmt_path="/proc/sys/fs/binfmt_misc/$binfmt_name" # Check if it's already registered (the file exists) if [ -f "$proc_binfmt_path" ]; then echo "$binfmt_name is already registered." else echo "Registering $binfmt_name..." # Read the content of the configuration file config_content=$(cat "$binfmt_file") # Parse the content to build the single-line format for /proc/sys/fs/binfmt_misc/register # Format: :name:type:offset:magic:mask:interpreter:flags # This parsing is a bit fragile in pure bash, assuming standard structure interpreter=$(echo "$config_content" | grep '^interpreter' | awk '{print $2}') magic=$(echo "$config_content" | grep '^magic' | cut -d' ' -f 2-) # Get hex bytes after 'magic ' mask=$(echo "$config_content" | grep '^mask' | cut -d' ' -f 2-)  # Get hex bytes after 'mask ' # Determine type (M for magic, F for script) - all qemu-user are M binfmt_type="M" binfmt_offset="0" # ELF magic is usually at offset 0 # Determine flags (C, P, F) flags="" if echo "$config_content" | grep -q '^credentials yes'; then flags+="C"; fi if echo "$config_content" | grep -q '^preserve yes'; then flags+="P"; fi if echo "$config_content" | grep -q '^fix_binary yes'; then flags+="F"; fi # Add other potential flags if needed, but CPF are common for qemu if [ -z "$interpreter" ] || [ -z "$magic" ] || [ -z "$mask" ]; then echo "Warning: Could not parse configuration for $binfmt_file. Skipping registration." continue # Skip to next file fi # Construct the registration string registration_string=":$binfmt_name:$binfmt_type:$binfmt_offset:$magic:$mask:$interpreter:$flags" # Write the string to the register file using sudo sh -c # The > /dev/null prevents the echo output from appearing if sudo sh -c "echo '$registration_string' > /proc/sys/fs/binfmt_misc/register"; then echo "$binfmt_name registered successfully." else echo "Warning: Failed to register $binfmt_name. This may impact builds for this architecture." # Don't exit, try to register others fi fi fi done echo "=> Verifying registration for qemu-aarch64..." if [ -f "/proc/sys/fs/binfmt_misc/qemu-aarch64" ]; then echo "Emulação qemu-aarch64 está ativa e registada." else echo "ERRO: O registo da emulação qemu-aarch64 falhou!" echo "A build para aarch64 provavelmente falhará com 'Erro de formato do executável'." # Don't exit here, as other registrations might have worked fi echo "=> Host environment setup complete." echo "You can now try running your iso_builder.py script for aarch64 (or another architecture)."