initial UEFI support, using isohybrid as default now
authorMichael Prokop <mika@grml.org>
Sat, 26 Nov 2011 23:28:42 +0000 (00:28 +0100)
committerMichael Prokop <mika@grml.org>
Tue, 29 Nov 2011 10:22:59 +0000 (11:22 +0100)
* restricted to amd64 only
* requires xorriso >=1.1.6-2 on build host
* requires recent syslinux version supporting --uefi
  (2:4.04+dfsg-9 known to be working) on build host
* requires grub-efi-amd64-bin in chroot (>=Debian/wheezy)

Thanks: Ulrich Dangel <mru@grml.org>
Ack-ed by: Christian Hofstaedtler <ch@grml.org>

etc/grml/fai/config/scripts/GRMLBASE/45-efi [new file with mode: 0755]
grml-live

diff --git a/etc/grml/fai/config/scripts/GRMLBASE/45-efi b/etc/grml/fai/config/scripts/GRMLBASE/45-efi
new file mode 100755 (executable)
index 0000000..f9ec40d
--- /dev/null
@@ -0,0 +1,74 @@
+#!/bin/bash
+# Filename:      ${GRML_FAI_CONFIG}/config/scripts/GRMLBASE/45-efi
+# Purpose:       create grub image for use in ISO for EFI boot
+# Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
+# Bug-Reports:   see http://grml.org/bugs/
+# License:       This file is licensed under the GPL v2 or any later version.
+################################################################################
+
+set -e
+
+if ! ifclass AMD64 ; then
+  echo "Not in AMD64 class but EFI feature is restricted to amd64 only, skipping."
+  exit 0
+fi
+
+set -u
+
+if ! [ -r "${target}"/usr/lib/grub/x86_64-efi/moddep.lst ] ; then
+  echo "/usr/lib/grub/x86_64-efi/moddep.lst could not be found, skipping."
+  echo "NOTE: grub-efi-amd64-bin not installed?"
+  exit 0
+fi
+
+GRUB_EFI_IMAGE="${target}/tmp/grub_efi_image"
+TMP_CONFIG="${target}/tmp/grub_config_efi"
+EFI_IMAGE="${target}/tmp/efi_image"
+
+rm -f "$GRUB_EFI_IMAGE" "$TMP_CONFIG" "$EFI_IMAGE"
+
+cat > "$TMP_CONFIG" <<EOF
+search --set -f /conf/bootid.txt root
+if [ -e /boot/grub/grub.cfg ]; then
+ set prefix=\$root/boot/grub
+ load_video
+ configfile /boot/grub/grub.cfg
+else
+ echo "E: Could not find root device!"
+fi
+EOF
+
+GRUB_EFI_IMAGE="${GRUB_EFI_IMAGE##${target}}"
+TMP_CONFIG="${TMP_CONFIG##${target}}"
+EFI_IMAGE="${EFI_IMAGE##${target}}"
+
+$ROOTCMD grub-mkimage -O x86_64-efi -o "$GRUB_EFI_IMAGE" --prefix=/boot/grub/ --config="$TMP_CONFIG" \
+  bitmap boot btrfs cat chain cmp configfile cpio echo efi_gop      \
+  efi_uga elf ext2 fat gfxmenu gfxterm gzio help iso9660 jpeg linux \
+  loopback lvm minicmd multiboot normal part_gpt part_msdos png     \
+  probe raid reiserfs search search_fs_file search_fs_uuid          \
+  search_label terminal test video videoinfo xfs
+
+if ! [ -r "${target}/${GRUB_EFI_IMAGE}" ] ; then
+  echo "Can not access grub efi image." >&2
+  exit 1
+fi
+
+SIZE=$(du -sk "${target}/${GRUB_EFI_IMAGE}" | awk -F" " '{print $1'})
+SIZE=$(((($SIZE / 32 )+2)*32))
+
+dd if=/dev/zero of="${target}/${EFI_IMAGE}" bs=1k count="$SIZE" 2>/dev/null
+$ROOTCMD mkfs.vfat -n GRML "$EFI_IMAGE" >/dev/null
+$ROOTCMD mmd -i "$EFI_IMAGE" ::EFI
+$ROOTCMD mmd -i "$EFI_IMAGE" ::EFI/BOOT
+$ROOTCMD mcopy -i "$EFI_IMAGE" "$GRUB_EFI_IMAGE" ::EFI/BOOT/bootx64.efi >/dev/null
+
+rm -f "${target}/${TMP_CONFIG}"
+mv "${target}/${EFI_IMAGE}" "${target}/var/lib/grml_live_efi.img"
+mv "${target}/${GRUB_EFI_IMAGE}" "${target}/var/lib/grml_live_bootx64.efi"
+
+echo "Generated EFI image ${target}/var/lib/grml_live_efi.img"
+echo "Generated bootx64 image ${target}/var/lib/grml_live_bootx64.efi"
+
+## END OF FILE #################################################################
+# vim:ft=sh expandtab ai tw=80 tabstop=4 shiftwidth=2
index b14320b..88d796f 100755 (executable)
--- a/grml-live
+++ b/grml-live
@@ -1185,17 +1185,53 @@ else
       einfo "Forcing rebuild of ISO because files on ISO have been modified."
    fi
 
-   # support mkisofs as well as genisoimage
-   if which mkisofs >/dev/null 2>&1; then
+   # support xorriso as well mkisofs and genisoimage
+   if which xorriso >/dev/null 2>&1 && \
+      dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-2 ; then
+      MKISOFS='xorriso -as mkisofs'
+    elif which mkisofs >/dev/null 2>&1; then
       MKISOFS='mkisofs'
    elif which genisoimage >/dev/null 2>&1; then
       MKISOFS='genisoimage'
    else
-      log    "Error: neither mkisofs nor genisoimage available - can not create ISO."
-      eerror "Error: neither mkisofs nor genisoimage available - can not create ISO." ; eend 1
+      log    "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO."
+      eerror "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." ; eend 1
       bailout
    fi
 
+   case "$ARCH" in
+     amd64)
+       # using -eltorito-alt-boot is limited to xorriso for now
+       case "$MKISOFS" in
+         xorriso*)
+           einfo "Using xorriso for ISO generation." ;  eend 0
+
+           if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" ] ; then
+             einfo "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
+             log   "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
+             mv "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" "${BUILD_OUTPUT}/boot/efi.img"
+             eend $?
+           fi
+
+           if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" ] ; then
+             einfo "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
+             log   "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
+             mkdir -p "${BUILD_OUTPUT}/efi/boot/"
+             mv "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi"
+             eend $?
+           fi
+
+           if [ -r "${BUILD_OUTPUT}"/boot/efi.img ] ; then
+             einfo "/boot/efi.img found and amd64 architecture present, extending boot arguments."
+             log   "/boot/efi.img found and amd64 architecture present, extending boot arguments."
+             BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
+             eend $?
+           fi
+           ;;
+       esac
+       ;;
+   esac
+
    CURRENT_DIR=$(pwd)
    if cd "$BUILD_OUTPUT" ; then
       if [ "$BOOT_METHOD" = "grub2" ]; then
@@ -1206,7 +1242,7 @@ else
             dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
       fi
       log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS -o ${ISO_OUTPUT}/${ISO_NAME} ."
-      "$MKISOFS" -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
+      $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
               -l -r -J $BOOT_ARGS -no-pad \
               -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
       # both of these need core.img there, so it’s easier to write it here
@@ -1228,28 +1264,10 @@ else
          log   "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
          einfo "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
          eend 0
-      # use isohybrid only on request
-      elif [ "$HYBRID_METHOD" = "isohybrid" ] ; then
-         if ! which isohybrid >/dev/null 2>&1 ; then
-           bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common"
-         else
-           log "Creating hybrid ISO file with isohybrid method"
-           einfo "Creating hybrid ISO file with isohybrid method"
-           # Notes for consideration:
-           # "-entry 4 -type 1c"
-           # * using 4 as the partition number is supposed to help with BIOSes
-           #   that only support USB-Zip boot
-           # * using 1c (i.e. hidden FAT32 LBA), instead of the default 0x17
-           #   (hidden NTFS, IIRC), as the partition type is sometimes needed
-           #   to get the BIOS even look at the partition created by isohybrid
-           isohybrid "${ISO_OUTPUT}/${ISO_NAME}"
-           eend $?
-         fi
-      # by default use our manifold boot method:
-      else
+      elif [ "$HYBRID_METHOD" = "manifold" ] ; then
          # isoinfo is part of both mkisofs and genisoimage so we're good
          bootoff=$(isoinfo -l -i "${ISO_OUTPUT}/${ISO_NAME}" | \
-           sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN;1 *$/s//\1/p')
+           sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN[;1]* *$/s//\1/p')
          if ! [ -r boot/grub/core.img ] ; then
            ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
          elif [ "${bootoff:-0}" -lt 1 ] ; then
@@ -1267,6 +1285,29 @@ else
            fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
            eend $?
          fi
+      # use isohybrid as default
+      else
+         if ! which isohybrid >/dev/null 2>&1 ; then
+           bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common"
+         else
+           log   "Creating hybrid ISO file with isohybrid method"
+           einfo "Creating hybrid ISO file with isohybrid method"
+           # Notes for consideration:
+           # "-entry 4 -type 1c"
+           # * using 4 as the partition number is supposed to help with BIOSes
+           #   that only support USB-Zip boot
+           # * using 1c (i.e. hidden FAT32 LBA), instead of the default 0x17
+           #   (hidden NTFS, IIRC), as the partition type is sometimes needed
+           #   to get the BIOS even look at the partition created by isohybrid
+           if isohybrid --help | grep -q -- --uefi ; then
+             einfo "Detected uefi support for isohybrid, enabling."
+             ISOHYBRID_OPTIONS=--uefi
+           fi
+
+           log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}"
+           isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}"
+           eend $?
+         fi
       fi
 
       # generate md5sum and sha1sum of ISO if we are using class 'RELEASE':