1. #!/bin/bash
  2.  
  3. # convert archboot.iso to gpt bootable for MacBookAir
  4. # works with archboot 2011.07-2
  5.  
  6. [[ $# -ne 2 ]] && echo "Usage: $0 <archboot-iso-file> <target-file>" && exit
  7.  
  8. ARCHBOOT_ISO=$1
  9. TARGET_FILE=$2
  10.  
  11. ARCHBOOT_DIR=$(mktemp -d)
  12. ESP_DIR=$(mktemp -d)
  13. SYSTEM_DIR=$(mktemp -d)
  14. TARGET_DIR=$(mktemp -d)
  15.  
  16. echo ========================Mounting archboot
  17. # Set up archboot for copying
  18. mount $ARCHBOOT_ISO -o loop $ARCHBOOT_DIR
  19.  
  20. echo ========================Preparing archboot files
  21. # We will use two partitions to store archboot in the target image.
  22. # The first partition is for EFI boot files, it MUST be fat32;
  23. # fat32 does not support soft links, which are used in Arch,
  24. # hence the need for a second partition.
  25. # Also, we only need x86_64, strip out i686 etc.
  26.  
  27. # First partition
  28. cp -r $ARCHBOOT_DIR/efi $ESP_DIR
  29. cat >$ESP_DIR/efi/grub2/grub.cfg <<EOF
  30. search --file --no-floppy --set=archboot /arch/archboot.txt
  31. set pager=1
  32. menuentry "Arch Linux MacBookAir3" {
  33. linux (\${archboot})/boot/vm64 nouveau.blacklist=1 noexec=off noefi nomodeset add_efi_memmap reboot=pci elevator=noop none=EFI_ARCH_\${_EFI_ARCH}
  34. initrd (\${archboot})/boot/initrd64.img
  35. }
  36. menuentry "Arch Linux MacBookAir4" {
  37. linux (\${archboot})/boot/vm64 i915.modeset=0 noexec=off noefi nomodeset add_efi_memmap reboot=pci elevator=noop none=EFI_ARCH_\${_EFI_ARCH}
  38. initrd (\${archboot})/boot/initrd64.img
  39. }
  40. EOF
  41. # Second partition
  42. cp -r $ARCHBOOT_DIR/{arch,boot,packages} $SYSTEM_DIR
  43. # No need for i686, can't EFI boot to that, nor the (old) lts kernel
  44. rm $SYSTEM_DIR/packages/archboot_packages_i686.squashfs
  45. rm $SYSTEM_DIR/boot/{initrd64lts.img,initrd.img,initrdlts.img,memtest,vm64lts,vmlinuz,vmlts}
  46. rm -r $SYSTEM_DIR/boot/syslinux
  47.  
  48. # Calculate target image size.
  49. # According to http://rodsbooks.com/gdisk/
  50. # we will need 2048*512 at the beginning of the disk,
  51. # 200MiB for the ESP boot partition.
  52. # Duplicate header/partition table stored at end of disk, we assume 2048*512 for symmetry.
  53. # According to http://projects.archlinux.org/archboot.git/tree/usr/bin/archboot-usbimage-helper.sh
  54. # the overhead for ext2 is <6%.  Assuming 4096-byte physical sector size
  55. # we calculate as follows.
  56. SYSTEM_SIZE=$(du -bs ${SYSTEM_DIR}|cut -f1)
  57. SYSTEM_PARTITION_SIZE=$(( ((${SYSTEM_SIZE}*106)/100/4096 + 1)*4096))
  58. IMAGE_SIZE=$(( ${SYSTEM_PARTITION_SIZE}+2*2048*512+200*2**20))
  59.  
  60. echo SYSTEM_SIZE=$SYSTEM_SIZE
  61. echo SYSTEM_PARTITION_SIZE=$SYSTEM_PARTITION_SIZE
  62. echo IMAGE_SIZE=$IMAGE_SIZE
  63.  
  64. echo ========================Creating target file
  65. dd if=/dev/zero of=$TARGET_FILE bs=${IMAGE_SIZE} count=1
  66.  
  67. # Create GPT partition table
  68. # Partition 1 starts at sector 2048, size is 200MiB, type EFI System Partition
  69. # Partition 2 fills the rest of the image
  70. echo ========================Setting up partition table
  71. sgdisk -o -n 1:2048:+200M -t 1:ef00 -n 2:0:0 $TARGET_FILE
  72.  
  73. # calculate extents, needed to create the filesystems
  74. BASE1=$(( 512 * $(sgdisk -i 1 $TARGET_FILE | grep 'First sector:' | cut -f 3 -d ' ') ))
  75. SIZE1=$(( 512 * $(sgdisk -i 1 $TARGET_FILE | grep 'Partition size:' | cut -f 3 -d ' ') ))
  76. BASE2=$(( 512 * $(sgdisk -i 2 $TARGET_FILE | grep 'First sector:' | cut -f 3 -d ' ') ))
  77. SIZE2=$(( 512 * $(sgdisk -i 2 $TARGET_FILE | grep 'Partition size:' | cut -f 3 -d ' ') ))
  78.  
  79. echo ========================PARTITION1
  80. # create fat32 file system on partition 1, copy bootloader files there
  81. LOOP=$(losetup -f --show --offset=$BASE1 --sizelimit=$SIZE1 $TARGET_FILE)
  82. mkfs.vfat -S 512 -F 32 $LOOP
  83. mount $LOOP $TARGET_DIR
  84. cp -r $ESP_DIR/* $TARGET_DIR
  85. umount $TARGET_DIR
  86. losetup -d $LOOP
  87.  
  88. echo ========================PARTITION2
  89. # create ext2 file system on partition 2, copy the rest of the system there
  90. LOOP=$(losetup -f --show --offset=$BASE2 --sizelimit=$SIZE2 $TARGET_FILE)
  91. mkfs.ext2 $LOOP
  92. mount $LOOP $TARGET_DIR
  93. cp -r $SYSTEM_DIR/* $TARGET_DIR
  94. umount $TARGET_DIR
  95. losetup -d $LOOP
  96.  
  97. echo ========================CLEANING UP
  98. # final cleanup
  99. umount $ARCHBOOT_DIR
  100. rmdir $ARCHBOOT_DIR $TARGET_DIR
  101. rm -rf $ESP_DIR $SYSTEM_DIR
  102.  
  103. echo ========================DONE
  104. echo You can overwrite your USB disk with
  105. echo "    dd if=$TARGET_FILE of=<device>"