# Define file/directory names IMG_NAME="${IMG_FILENAME}${IMG_SUFFIX}" IMG_FILE="${STAGE_WORK_DIR}/${IMG_NAME}.img" MOUNT_DIR="${ROOTFS_DIR}" # Consistent name for the main rootfs mount point # Define partition sizes BOOT_SIZE=$((512 * 1024 * 1024)) # 512MB RECOVERY_SIZE=$((256 * 1024 * 1024)) # 256MB ALIGN=$((4 * 1024 * 1024)) # 4MB alignment # --- Cleanup --- echo "--- Cleaning up previous artifacts ---" # Assume unmount_image handles unmounting potential mounts and detaching loop device unmount_image "${IMG_FILE}" rm -f "${IMG_FILE}" rm -rf "${MOUNT_DIR}" mkdir -p "${MOUNT_DIR}" # --- Calculate Image Size --- echo "--- Calculating required image size ---" # Calculate rootfs size excluding caches and firmware placeholder ROOT_SIZE=$(du -x --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/apt/archives --exclude boot/firmware --block-size=1 | cut -f 1) # Add a margin for overhead and future growth (using mk-img.sh margin) ROOT_MARGIN="$(echo "($ROOT_SIZE * 0.2 + 400 * 1024 * 1024) / 1" | bc)" # Calculate aligned partition sizes and starts BOOT_PART_START=$((ALIGN)) BOOT_PART_SIZE=$(((BOOT_SIZE + ALIGN - 1) / ALIGN * ALIGN)) ROOT_PART_START=$((BOOT_PART_START + BOOT_PART_SIZE)) ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN)) RECOVERY_PART_START=$((ROOT_PART_START + ROOT_PART_SIZE)) RECOVERY_PART_SIZE=$(((RECOVERY_SIZE + ALIGN - 1) / ALIGN * ALIGN)) IMG_SIZE=$((RECOVERY_PART_START + RECOVERY_PART_SIZE)) echo "Rootfs Size: ${ROOT_SIZE} B" echo "Root Margin: ${ROOT_MARGIN} B" echo "Calculated Image Size: ${IMG_SIZE} B" # --- Create Raw Image File --- echo "--- Creating raw image file: ${IMG_FILE} ---" truncate -s "${IMG_SIZE}" "${IMG_FILE}" # --- Partition the Image --- echo "--- Partitioning the image ---" parted --script "${IMG_FILE}" mklabel msdos parted --script "${IMG_FILE}" unit B set 1 boot on # Set boot flag on partition 1 parted --script "${IMG_FILE}" unit B mkpart primary fat32 "${BOOT_PART_START}" "$((BOOT_PART_START + BOOT_PART_SIZE - 1))" parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${ROOT_PART_START}" "$((ROOT_PART_START + ROOT_PART_SIZE - 1))" parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${RECOVERY_PART_START}" "$((RECOVERY_PART_START + RECOVERY_PART_SIZE - 1))" # --- Setup Loop Device --- echo "--- Setting up loop device ---" cnt=0 # Assume ensure_next_loopdev() ensures a free loop device is available until ensure_next_loopdev && LOOP_DEV="$(losetup --show --find --partscan "$IMG_FILE")"; do ((cnt++)) if [ $cnt -ge 5 ]; then echo "ERROR: losetup failed after 5 attempts." exit 1 fi echo "Error setting up loop device. Retrying (${cnt}/5)..." sleep 5 done echo "Loop device created: ${LOOP_DEV}" # Assume ensure_loopdev_partitions() waits for partition nodes (e.g., /dev/loopXp1) to appear ensure_loopdev_partitions "$LOOP_DEV" BOOT_DEV="${LOOP_DEV}p1" ROOT_DEV="${LOOP_DEV}p2" RECOVERY_DEV="${LOOP_DEV}p3" # --- Format Partitions --- echo "--- Formatting partitions ---" # Determine EXT4 features (disable 64bit if not supported/needed, keep ^huge_file) ROOT_FEATURES="^huge_file" if grep -q "64bit" /etc/mke2fs.conf; then ROOT_FEATURES="^64bit,$ROOT_FEATURES" echo "Enabling 64bit feature for ext4." fi # Determine FAT size for boot partition if [ "$BOOT_SIZE" -lt 134742016 ]; then # Approx 128MiB FAT_SIZE=16 echo "Using FAT16 for boot partition." else FAT_SIZE=32 echo "Using FAT32 for boot partition." fi mkdosfs -n BOOT -F "$FAT_SIZE" -s 4 -v "$BOOT_DEV" > /dev/null mkfs.ext4 -L rootfs -O "$ROOT_FEATURES" "$ROOT_DEV" > /dev/null mkfs.ext4 -L recovery -O "$ROOT_FEATURES" "$RECOVERY_DEV" > /dev/null # Format recovery for all archs # --- Architecture-Specific Steps --- if [ "$ARCH" == "amd64" ]; then # --- AMD64: Create IMG, Install GRUB, Create ISO --- echo "--- Running AMD64 specific steps (IMG + GRUB + ISO) ---" ISO_STAGING_DIR="${STAGE_WORK_DIR}/iso_staging" # Temp dir for ISO contents # Mount partitions for AMD64 (boot on /boot) echo "Mounting partitions for AMD64..." mount -v "$ROOT_DEV" "${MOUNT_DIR}" -t ext4 mkdir -p "${MOUNT_DIR}/boot" mount -v "$BOOT_DEV" "${MOUNT_DIR}/boot" -t vfat # Optional: Mount recovery if you need to add specific recovery tools to the ISO # mkdir -p "${MOUNT_DIR}/recovery" # mount -v "$RECOVERY_DEV" "${MOUNT_DIR}/recovery" -t ext4 # Copy root filesystem content (excluding caches, firmware, overlays which are typically ARM specific) echo "Copying root filesystem..." rsync -aHAXx --delete --exclude /var/cache/apt/archives --exclude /boot/firmware --exclude /boot/overlays "${EXPORT_ROOTFS_DIR}/" "${MOUNT_DIR}/" # Install GRUB bootloader for BIOS boot echo "Installing GRUB (BIOS)..." mkdir -p "${MOUNT_DIR}/boot/grub" # Ensure grub dir exists # Basic GRUB config - **IMPORTANT**: Adjust kernel/initrd paths and root= parameter if needed! # Using PARTUUID is generally more reliable than /dev/sdxN ROOT_PARTUUID=$(blkid -s PARTUUID -o value "$ROOT_DEV") cat > "${MOUNT_DIR}/boot/grub/grub.cfg" <