164 lines
7.5 KiB
Bash
Executable File
164 lines
7.5 KiB
Bash
Executable File
#!/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 <command>' 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)."
|