#!/bin/bash
# convert archboot.iso to gpt bootable for MacBookAir
# works with archboot 2011.07-2
[[ $# -ne 2 ]] && echo "Usage: $0 <archboot-iso-file> <target-file>" && exit
ARCHBOOT_ISO=$1
TARGET_FILE=$2
ARCHBOOT_DIR=$(mktemp -d)
ESP_DIR=$(mktemp -d)
SYSTEM_DIR=$(mktemp -d)
TARGET_DIR=$(mktemp -d)
echo ========================Mounting archboot
# Set up archboot for copying
mount $ARCHBOOT_ISO -o loop $ARCHBOOT_DIR
echo ========================Preparing archboot files
# We will use two partitions to store archboot in the target image.
# The first partition is for EFI boot files, it MUST be fat32;
# fat32 does not support soft links, which are used in Arch,
# hence the need for a second partition.
# Also, we only need x86_64, strip out i686 etc.
# First partition
cp -r $ARCHBOOT_DIR/efi $ESP_DIR
cat >$ESP_DIR/efi/grub2/grub.cfg <<EOF
search --file --no-floppy --set=archboot /arch/archboot.txt
set pager=1
menuentry "Arch Linux MacBookAir3" {
linux (\${archboot})/boot/vm64 nouveau.blacklist=1 noexec=off noefi nomodeset add_efi_memmap reboot=pci elevator=noop none=EFI_ARCH_\${_EFI_ARCH}
initrd (\${archboot})/boot/initrd64.img
}
menuentry "Arch Linux MacBookAir4" {
linux (\${archboot})/boot/vm64 i915.modeset=0 noexec=off noefi nomodeset add_efi_memmap reboot=pci elevator=noop none=EFI_ARCH_\${_EFI_ARCH}
initrd (\${archboot})/boot/initrd64.img
}
EOF
# Second partition
cp -r $ARCHBOOT_DIR/{arch,boot,packages} $SYSTEM_DIR
# No need for i686, can't EFI boot to that, nor the (old) lts kernel
rm $SYSTEM_DIR/packages/archboot_packages_i686.squashfs
rm $SYSTEM_DIR/boot/{initrd64lts.img,initrd.img,initrdlts.img,memtest,vm64lts,vmlinuz,vmlts}
rm -r $SYSTEM_DIR/boot/syslinux
# Calculate target image size.
# According to http://rodsbooks.com/gdisk/
# we will need 2048*512 at the beginning of the disk,
# 200MiB for the ESP boot partition.
# Duplicate header/partition table stored at end of disk, we assume 2048*512 for symmetry.
# According to http://projects.archlinux.org/archboot.git/tree/usr/bin/archboot-usbimage-helper.sh
# the overhead for ext2 is <6%. Assuming 4096-byte physical sector size
# we calculate as follows.
SYSTEM_SIZE=$(du -bs ${SYSTEM_DIR}|cut -f1)
SYSTEM_PARTITION_SIZE=$(( ((${SYSTEM_SIZE}*106)/100/4096 + 1)*4096))
IMAGE_SIZE=$(( ${SYSTEM_PARTITION_SIZE}+2*2048*512+200*2**20))
echo SYSTEM_SIZE=$SYSTEM_SIZE
echo SYSTEM_PARTITION_SIZE=$SYSTEM_PARTITION_SIZE
echo IMAGE_SIZE=$IMAGE_SIZE
echo ========================Creating target file
dd if=/dev/zero of=$TARGET_FILE bs=${IMAGE_SIZE} count=1
# Create GPT partition table
# Partition 1 starts at sector 2048, size is 200MiB, type EFI System Partition
# Partition 2 fills the rest of the image
echo ========================Setting up partition table
sgdisk -o -n 1:2048:+200M -t 1:ef00 -n 2:0:0 $TARGET_FILE
# calculate extents, needed to create the filesystems
BASE1=$(( 512 * $(sgdisk -i 1 $TARGET_FILE | grep 'First sector:' | cut -f 3 -d ' ') ))
SIZE1=$(( 512 * $(sgdisk -i 1 $TARGET_FILE | grep 'Partition size:' | cut -f 3 -d ' ') ))
BASE2=$(( 512 * $(sgdisk -i 2 $TARGET_FILE | grep 'First sector:' | cut -f 3 -d ' ') ))
SIZE2=$(( 512 * $(sgdisk -i 2 $TARGET_FILE | grep 'Partition size:' | cut -f 3 -d ' ') ))
echo ========================PARTITION1
# create fat32 file system on partition 1, copy bootloader files there
LOOP=$(losetup -f --show --offset=$BASE1 --sizelimit=$SIZE1 $TARGET_FILE)
mkfs.vfat -S 512 -F 32 $LOOP
mount $LOOP $TARGET_DIR
cp -r $ESP_DIR/* $TARGET_DIR
umount $TARGET_DIR
losetup -d $LOOP
echo ========================PARTITION2
# create ext2 file system on partition 2, copy the rest of the system there
LOOP=$(losetup -f --show --offset=$BASE2 --sizelimit=$SIZE2 $TARGET_FILE)
mkfs.ext2 $LOOP
mount $LOOP $TARGET_DIR
cp -r $SYSTEM_DIR/* $TARGET_DIR
umount $TARGET_DIR
losetup -d $LOOP
echo ========================CLEANING UP
# final cleanup
umount $ARCHBOOT_DIR
rmdir $ARCHBOOT_DIR $TARGET_DIR
rm -rf $ESP_DIR $SYSTEM_DIR
echo ========================DONE
echo You can overwrite your USB disk with
echo " dd if=$TARGET_FILE of=<device>"