Secure Boot support
authorMichael Prokop <mika@grml.org>
Thu, 31 Aug 2017 00:54:32 +0000 (02:54 +0200)
committerMichael Prokop <mika@grml.org>
Thu, 31 Aug 2017 00:54:32 +0000 (02:54 +0200)
Thanks to the way the signed GRUB by Ubuntu works we seem to be
able to keep our common EFI GRUB configs working next to the new
Secure Boot related EFI GRUB configs. If Secure Boot is enabled
we get the same look and feel like with common EFI boot, though
with a Secure Boot specific boot menu (since e.g. the linux16
command isn't available under Secure Boot). If EFI is running
with Secure Boot *disabled* it continues to look like it used to
do so far. If this is working out as planned there's no visible
change from a user point of view on systems with Secure Boot
disabled.

With this change we also get rid of some magic with grml-live
relying on behavior of
/etc/grml/fai/config/scripts/GRMLBASE/45-grub-images, including
moving files around.

We also no longer skip the boot stage during rebuilds. This has
been a source of frustration and annoying debugging sessions when
files inside grml_cd/boot/ didn't receive changes during rebuilds
and the user in front of the system is ignoring the according
"skip" notice or forgot to remove grml_cd/boot.

While at it rewrite debian/copyright in
http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/

Thanks: Michael Schierl <schierlm@gmx.de> for help regarding the Secure Boot setup

12 files changed:
debian/control
debian/copyright
debian/grml-live.install
etc/grml/fai/config/scripts/GRMLBASE/45-grub-images
etc/grml/grml-live.conf
grml-live
templates/EFI/BOOT/README [new file with mode: 0644]
templates/EFI/BOOT/grubx64.efi.signed [new file with mode: 0644]
templates/EFI/BOOT/shimx64.efi.signed [new file with mode: 0644]
templates/EFI/ubuntu/grub.cfg [new file with mode: 0644]
templates/boot/grub/grmlenv.cfg [new file with mode: 0644]
templates/secureboot/grub.cfg [new file with mode: 0644]

index 2792a25..690b397 100644 (file)
@@ -17,12 +17,14 @@ Package: grml-live
 Architecture: all
 Depends: bc,
          bzip2,
+         dosfstools,
          fai-client (>= 3.4.0),
          fai-server (>= 3.4.0),
          isolinux (>= 3:6.03+dfsg-5+deb8u1~),
          memtest86+,
          mksh,
          moreutils,
+         mtools,
          pciutils,
          rsync,
          squashfs-tools (>= 1:4.2-0~bpo60),
index d75570a..98b6759 100644 (file)
-This package was debianized by Michael Prokop <mika@grml.org> on
-Sat, 15 Sep 2007 15:35:34 +0200.
-
-It was downloaded from http://grml.org/
-
-Upstream Author: Michael Prokop <mika@grml.org>
-
-Copyright:
-
-    © 2007++ by Michael Prokop <mika@grml.org>
-
-License:
-
-    This package is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This package is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this package; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
-
-License information for the syslinux files shipped as
-/usr/share/grml-live/templates/boot/isolinux/:
-
-   Downloaded from <http://ftp.kernel.org/pub/linux/utils/boot/syslinux/>.
-   Upstream Author: H. Peter Anvin <hpa@zytor.com>
-   Copyright (C) 1994-2007 H. Peter Anvin <hpa@zytor.com>
-
-On Debian systems, the complete text of the GNU General
-Public License can be found in `/usr/share/common-licenses/GPL'.
-
-The Debian packaging is © 2007++, Michael Prokop <mika@grml.org> and
-is licensed under the GPL, see above.
-
-License information for the graphicore Bitmap Font shipped as
-/usr/share/grml-live/fonts/:
-  Downloaded from <https://github.com/graphicore/graphicoreBMFB/downloads>
-  Upstream Author: Lasse Fister <lasse@graphicore.de>
-  Copyright (c) 2010, Lasse Fister lasse@graphicore.de
-
-License:
-   -----------------------------------------------------------
-   SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-   -----------------------------------------------------------
-
-   PREAMBLE
-   The goals of the Open Font License (OFL) are to stimulate worldwide
-   development of collaborative font projects, to support the font creation
-   efforts of academic and linguistic communities, and to provide a free and
-   open framework in which fonts may be shared and improved in partnership
-   with others.
-
-   The OFL allows the licensed fonts to be used, studied, modified and
-   redistributed freely as long as they are not sold by themselves. The
-   fonts, including any derivative works, can be bundled, embedded,
-   redistributed and/or sold with any software provided that any reserved
-   names are not used by derivative works. The fonts and derivatives,
-   however, cannot be released under any other type of license. The
-   requirement for fonts to remain under this license does not apply
-   to any document created using the fonts or their derivatives.
-
-   DEFINITIONS
-   "Font Software" refers to the set of files released by the Copyright
-   Holder(s) under this license and clearly marked as such. This may
-   include source files, build scripts and documentation.
-
-   "Reserved Font Name" refers to any names specified as such after the
-   copyright statement(s).
-
-   "Original Version" refers to the collection of Font Software components as
-   distributed by the Copyright Holder(s).
-
-   "Modified Version" refers to any derivative made by adding to, deleting,
-   or substituting -- in part or in whole -- any of the components of the
-   Original Version, by changing formats or by porting the Font Software to a
-   new environment.
-
-   "Author" refers to any designer, engineer, programmer, technical
-   writer or other person who contributed to the Font Software.
-
-   PERMISSION & CONDITIONS
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of the Font Software, to use, study, copy, merge, embed, modify,
-   redistribute, and sell modified and unmodified copies of the Font
-   Software, subject to the following conditions:
-
-   1) Neither the Font Software nor any of its individual components,
-   in Original or Modified Versions, may be sold by itself.
-
-   2) Original or Modified Versions of the Font Software may be bundled,
-   redistributed and/or sold with any software, provided that each copy
-   contains the above copyright notice and this license. These can be
-   included either as stand-alone text files, human-readable headers or
-   in the appropriate machine-readable metadata fields within text or
-   binary files as long as those fields can be easily viewed by the user.
-
-   3) No Modified Version of the Font Software may use the Reserved Font
-   Name(s) unless explicit written permission is granted by the corresponding
-   Copyright Holder. This restriction only applies to the primary font name as
-   remain under this license does not apply to any document created
-   using the Font Software.
-
-   TERMINATION
-   This license becomes null and void if any of the above conditions are
-   not met.
-
-   DISCLAIMER
-   THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-   OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
-   COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-   DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-   FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
-   /OTHER DEALINGS IN THE FONT SOFTWARE.
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: grml-live
+Upstream-Contact: Michael Prokop <mika@grml.org>
+Source: https://github.com/grml/grml-live/
+
+Files: *
+Copyright: 2007-2017 Michael Prokop <mika@grml.org>
+License: GPL-2+
+
+Files: fonts/graphicoreBitmapFont0-Light.otf
+Copyright: 2010, Lasse Fister lasse@graphicore.de
+License: SIL
+
+Files: scripts/bootgrub.mksh scripts/bootilnx.mksh
+Copyright: 2007, 2008, 2009, 2010 Thorsten Glaser <tg@mirbsd.org>
+License: MirOS
+
+Files: templates/EFI/BOOT/grubx64.efi.signed
+Copyright: 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc
+           2012 Canonical Ltd.
+Comment: /usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed from http://de.archive.ubuntu.com/ubuntu/pool/main/g/grub2-signed/grub-efi-amd64-signed_1.80.2+2.02~beta3-4ubuntu2.2_amd64.deb
+License: GPL-3+
+
+Files: templates/EFI/BOOT/shimx64.efi.signed
+Copyright: 2012 Red Hat, Inc
+           2009-2012 Intel Corporation
+Comment: /usr/lib/shim/shimx64.efi.signed from http://de.archive.ubuntu.com/ubuntu/pool/main/s/shim-signed/shim-signed_1.32~17.04.1+0.9+1474479173.6c180c6-1ubuntu1_amd64.deb
+License: BSD-2-Clause
+
+License: GPL-2
+ On Debian systems the full text of the GNU General Public License can be
+ found in the `/usr/share/common-licenses/GPL-2' file.
+
+License: GPL-2+
+ On Debian systems the full text of the GNU General Public License can be
+ found in the `/usr/share/common-licenses/GPL-2' file.
+
+License: GPL-3+
+ On Debian systems the full text of the GNU General Public License can be
+ found in the `/usr/share/common-licenses/GPL-3' file.
+
+License: BSD-2-Clause
+ Copyright (c) The Regents of the University of California.
+ All rights reserved.
+ .
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+License: MirOS
+ Provided that these terms and disclaimer and all copyright notices
+ are retained or reproduced in an accompanying document, permission
+ is granted to deal in this work without restriction, including un‐
+ limited rights to use, publicly perform, distribute, sell, modify,
+ merge, give away, or sublicence.
+ .
+ This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
+ the utmost extent permitted by applicable law, neither express nor
+ implied; without malicious intent or gross negligence. In no event
+ may a licensor, author or contributor be held liable for indirect,
+ direct, other damage, loss, or other issues arising in any way out
+ of dealing in the work, even if advised of the possibility of such
+ damage or existence of a defect, except proven that it results out
+ of said person’s immediate fault when using the work as intended.
+
+License: SIL
+ -----------------------------------------------------------
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+ -----------------------------------------------------------
+ .
+ PREAMBLE
+ The goals of the Open Font License (OFL) are to stimulate worldwide
+ development of collaborative font projects, to support the font creation
+ efforts of academic and linguistic communities, and to provide a free and
+ open framework in which fonts may be shared and improved in partnership
+ with others.
+ .
+ The OFL allows the licensed fonts to be used, studied, modified and
+ redistributed freely as long as they are not sold by themselves. The
+ fonts, including any derivative works, can be bundled, embedded,
+ redistributed and/or sold with any software provided that any reserved
+ names are not used by derivative works. The fonts and derivatives,
+ however, cannot be released under any other type of license. The
+ requirement for fonts to remain under this license does not apply
+ to any document created using the fonts or their derivatives.
+ .
+ DEFINITIONS
+ "Font Software" refers to the set of files released by the Copyright
+ Holder(s) under this license and clearly marked as such. This may
+ include source files, build scripts and documentation.
+ .
+ "Reserved Font Name" refers to any names specified as such after the
+ copyright statement(s).
+ .
+ "Original Version" refers to the collection of Font Software components as
+ distributed by the Copyright Holder(s).
+ .
+ "Modified Version" refers to any derivative made by adding to, deleting,
+ or substituting -- in part or in whole -- any of the components of the
+ Original Version, by changing formats or by porting the Font Software to a
+ new environment.
+ .
+ "Author" refers to any designer, engineer, programmer, technical
+ writer or other person who contributed to the Font Software.
+ .
+ PERMISSION & CONDITIONS
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
+ redistribute, and sell modified and unmodified copies of the Font
+ Software, subject to the following conditions:
+ .
+ 1) Neither the Font Software nor any of its individual components,
+ in Original or Modified Versions, may be sold by itself.
+ .
+ 2) Original or Modified Versions of the Font Software may be bundled,
+ redistributed and/or sold with any software, provided that each copy
+ contains the above copyright notice and this license. These can be
+ included either as stand-alone text files, human-readable headers or
+ in the appropriate machine-readable metadata fields within text or
+ binary files as long as those fields can be easily viewed by the user.
+ .
+ 3) No Modified Version of the Font Software may use the Reserved Font
+ Name(s) unless explicit written permission is granted by the corresponding
+ Copyright Holder. This restriction only applies to the primary font name as
+ remain under this license does not apply to any document created
+ using the Font Software.
+ .
+ TERMINATION
+ This license becomes null and void if any of the above conditions are
+ not met.
+ .
+ DISCLAIMER
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+ /OTHER DEALINGS IN THE FONT SOFTWARE.
index 9bb8d9e..a9cfbac 100644 (file)
@@ -6,7 +6,9 @@ fonts                       usr/share/grml-live/
 grml-live                   usr/sbin/
 remaster/grml-live-remaster usr/sbin/
 scripts                     usr/share/grml-live/
+templates/EFI               usr/share/grml-live/templates/
 templates/GRML              usr/share/grml-live/templates/
 templates/boot/grub         usr/share/grml-live/templates/boot/
 templates/boot/isolinux     usr/share/grml-live/templates/boot/
+templates/secureboot        usr/share/grml-live/templates/
 templates/windows           usr/share/grml-live/templates/
index 42ed130..84bc178 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/bash
-# Filename:      ${GRML_FAI_CONFIG}/config/scripts/GRMLBASE/45-efi
-# Purpose:       create grub image for use in ISO for EFI boot
+# Filename:      ${GRML_FAI_CONFIG}/config/scripts/GRMLBASE/45-grub-images
+# Purpose:       create grub images for use in ISO
 # 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.
@@ -9,15 +9,9 @@
 set -e
 set -u
 
+TMP_CONFIG="/tmp/grub_config_efi"
 
-BOOTX64="${target}/boot/bootx64.efi"
-BOOTX32="${target}/boot/bootia32.efi"
-EFI_IMG="${target}/boot/efi.img"
-TMP_CONFIG="${target}/tmp/grub_config_efi"
-
-rm -f "$BOOTX64" "$EFI_IMG" "$TMP_CONFIG"
-
-cat > "$TMP_CONFIG" <<EOF
+cat > "${target}/${TMP_CONFIG}" <<EOF
 search.file /conf/bootid.txt root
 set prefix=(\$root)/boot/grub
 insmod normal
@@ -25,13 +19,7 @@ normal
 echo "E: Could not find root device!"
 EOF
 
-BOOTX64="${BOOTX64##${target}}"
-BOOTX32="${BOOTX32##${target}}"
-EFI_IMG="${EFI_IMG##${target}}"
-TMP_CONFIG="${TMP_CONFIG##${target}}"
-
 ARCHS=(i386-pc)
-
 declare -A ADDITIONAL_MODULES
 ADDITIONAL_MODULES[i386-pc]="biosdisk"
 
@@ -43,7 +31,9 @@ if ifclass AMD64 ; then
     echo "/usr/lib/grub/x86_64-efi/moddep.lst could not be found, skipping."
     echo "NOTE: grub-efi-amd64-bin not installed?"
   fi
-elif ifclass I386 ; then
+fi
+
+if ifclass I386 ; then
   if [ -r "${target}"/usr/lib/grub/i386-efi/moddep.lst ] ; then
     ARCHS+=(i386-efi)
     ADDITIONAL_MODULES[i386-efi]="efi_gop efi_uga"
@@ -53,53 +43,20 @@ elif ifclass I386 ; then
   fi
 fi
 
-for arch in ${ARCHS[@]} ; do
-  $ROOTCMD grub-mkimage -O $arch -o /boot/$arch.img --prefix=/boot/grub/ --config="$TMP_CONFIG" \
+for arch in "${ARCHS[@]}" ; do
+  filename=''
+  case "$arch" in
+    i386-pc)    filename=/boot/grub/grub.img ;;
+    x86_64-efi) filename=/boot/bootx64.efi   ;;
+    i386-efi)   filename=/boot/bootia32.efi  ;;
+  esac
+
+  $ROOTCMD grub-mkimage -O $arch -o "$filename" --prefix=/boot/grub/ --config="$TMP_CONFIG" \
     echo iso9660 part_msdos search_fs_file test \
     fat ext2 reiserfs xfs btrfs squash4 part_gpt lvm \
     ${ADDITIONAL_MODULES[$arch]}
 done
 
-if [ -f "${target}/boot/i386-pc.img" ] ; then
-  mv "${target}/boot/i386-pc.img" "${target}/boot/grub/grub.img"
-fi
-
-if [ -f "${target}/boot/x86_64-efi.img" ] ; then
-  mv "${target}/boot/x86_64-efi.img" "${target}/${BOOTX64}"
-fi
-
-if [ -f "${target}/boot/i386-efi.img" ] ; then
-  mv "${target}/boot/i386-efi.img" "${target}/${BOOTX32}"
-fi
-
-if ifclass AMD64 ; then
-  if ! [ -r "${target}/${BOOTX64}" ] ; then
-    echo "Can not access grub efi image ${BOOTX64}." >&2
-    exit 1
-  fi
-
-  dd if=/dev/zero of="${target}/${EFI_IMG}" bs=4M count=1 2>/dev/null
-  $ROOTCMD mkfs.vfat -n GRML "$EFI_IMG" >/dev/null
-  $ROOTCMD mmd -i "$EFI_IMG" ::EFI
-  $ROOTCMD mmd -i "$EFI_IMG" ::EFI/BOOT
-  $ROOTCMD mcopy -i "$EFI_IMG" "$BOOTX64" ::EFI/BOOT/bootx64.efi >/dev/null
-  echo "Generated 64-bit EFI image $BOOTX64"
-elif ifclass I386 ; then
-  if ! [ -r "${target}/${BOOTX32}" ] ; then
-    echo "Can not access grub efi image ${BOOTX32}." >&2
-    exit 1
-  fi
-
-  dd if=/dev/zero of="${target}/${EFI_IMG}" bs=4M count=1 2>/dev/null
-  $ROOTCMD mkfs.vfat -n GRML "$EFI_IMG" >/dev/null
-  $ROOTCMD mmd -i "$EFI_IMG" ::EFI
-  $ROOTCMD mmd -i "$EFI_IMG" ::EFI/BOOT
-  $ROOTCMD mcopy -i "$EFI_IMG" "$BOOTX32" ::EFI/BOOT/bootia32.efi >/dev/null
-  echo "Generated 32-bit EFI image $BOOTX32"
-fi
-
-echo "Generated EFI image $EFI_IMG"
-
 rm -f "${target}/${TMP_CONFIG}"
 echo "Generated Grub images"
 
index c4dc978..af03a91 100644 (file)
 # HYBRID_METHOD='grub2'     # use manifold with GRUB 2
 # HYBRID_METHOD='manifold'  # use manifold with ISOLINUX (default)
 
+# By default Secure Boot is enabled using the approach from Ubuntu.
+# Currently only the Ubuntu approach is supported, which is restricted
+# to loading Linux kernels and using a minimal version of GRUB.
+# If unset defaults to "ubuntu"
+# SECURE_BOOT='disable'         # do not enable Secure Boot
+# SECURE_BOOT="ubuntu"          # use approach from Ubuntu
+
 # Binary that should be used for creating the squashfs file.
 # Defaults to the executable matching the kernel version, falls back to mksquashfs.
 # SQUASHFS_BINARY='mksquashfs'
index 2e7aad7..f561355 100755 (executable)
--- a/grml-live
+++ b/grml-live
@@ -310,6 +310,37 @@ copy_addon_file() {
   ewarn "$msg" ; eend 1
   log "copy_addon_file: $msg"
 }
+
+# replace placeholders in template files with actual information
+adjust_boot_files() {
+  if [ -z "$1" ] ; then
+    echo "Usage: adjust_boot_files <template_file>" >&2
+    exit 1
+  fi
+
+  for file in "$@" ; do
+    if [ -r "${file}" ] && [ -f "${file}" ] ; then
+      sed -i "s/%ARCH%/$ARCH/g"                    "${file}"
+      sed -i "s/%DATE%/$DATE/g"                    "${file}"
+      sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g"      "${file}"
+      sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g"      "${file}"
+      sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g"  "${file}"
+      sed -i "s/%GRML_NAME%/$GRML_NAME/g"          "${file}"
+      sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g"  "${file}"
+      sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g"    "${file}"
+      sed -i "s/%SHORT_NAME%/$SHORT_NAME/g"        "${file}"
+      sed -i "s/%VERSION%/$VERSION/g"              "${file}"
+
+      [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s; boot=live; boot=live $DEFAULT_BOOTOPTIONS;"  "${file}"
+
+      if [ -n "$NO_BOOTID" ] ; then
+        sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
+      else
+        sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
+      fi
+    fi
+  done
+}
 # }}}
 
 # command line parsing {{{
@@ -394,6 +425,7 @@ fi
 [ -n "$HOSTNAME" ]                || HOSTNAME='grml'
 [ -n "$HYBRID_METHOD" ]           || HYBRID_METHOD='isohybrid'
 [ -n "$RELEASENAME" ]             || RELEASENAME='grml-live rocks'
+[ -n "$SECURE_BOOT" ]             || SECURE_BOOT='ubuntu'
 [ -n "$SQUASHFS_EXCLUDES_FILE" ]  || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
 [ -n "$SUITE" ]                   || SUITE='testing'
 [ -n "$TEMPLATE_DIRECTORY" ]      || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
@@ -850,6 +882,86 @@ EOF
 fi
 # }}}
 
+# grub boot {{{
+grub_setup() {
+  BOOTX64="/boot/bootx64.efi"
+  BOOTX32="/boot/bootia32.efi"
+  EFI_IMG="/boot/efi.img"
+
+  if [[ "$ARCH" == "amd64" ]] ; then
+    # important: this depends on execution of ${GRML_FAI_CONFIG}/config/scripts/GRMLBASE/45-grub-images
+    if ! [ -r "${CHROOT_OUTPUT}/${BOOTX64}" ] ; then
+      log    "Can not access GRUB efi image ${CHROOT_OUTPUT}/${BOOTX64}, required for Secure Boot support"
+      eerror "Can not access GRUB efi image ${CHROOT_OUTPUT}/${BOOTX64}, required for Secure Boot support" ; eend 1
+      log    "Possible reason is failure to run ${GRML_FAI_CONFIG}/config/scripts/GRMLBASE/45-grub-images"
+      ewarn  "Possible reason is failure to run ${GRML_FAI_CONFIG}/config/scripts/GRMLBASE/45-grub-images"
+      bailout 50
+    fi
+
+    dd if=/dev/zero of="${CHROOT_OUTPUT}/${EFI_IMG}" bs=4M count=1 2>/dev/null || bailout 50
+    mkfs.vfat -n GRML "${CHROOT_OUTPUT}/${EFI_IMG}" >/dev/null || bailout 51
+    mmd -i "${CHROOT_OUTPUT}/${EFI_IMG}" ::EFI || bailout 52
+    mmd -i "${CHROOT_OUTPUT}/${EFI_IMG}" ::EFI/BOOT || bailout 52
+
+    if [ "${SECURE_BOOT:-}" = "disable" ] ; then
+      log   "Secure Boot is disabled."
+      einfo "Secure Boot is disabled." ; eend 0
+
+      # install "$BOOTX64" as ::EFI/BOOT/bootx64.efi inside image file "$EFI_IMG":
+      mcopy -i "${CHROOT_OUTPUT}/${EFI_IMG}" "${CHROOT_OUTPUT}/${BOOTX64}" ::EFI/BOOT/bootx64.efi >/dev/null || bailout 53
+
+      log   "Generated 64-bit EFI image $BOOTX64"
+      einfo "Generated 64-bit EFI image $BOOTX64" ; eend 0
+    else
+      log   "Secure Boot is enabled [mode: $SECURE_BOOT]"
+      einfo "Secure Boot is enabled [mode: $SECURE_BOOT]" ; eend 0
+
+      if [ "${SECURE_BOOT}" = "ubuntu" ] ; then
+        local GRUBCFG_TEMPLATE="${TEMPLATE_DIRECTORY}/secureboot/grub.cfg"
+        local GRUBCFG_TMP=$(mktemp)
+
+        if ! [ -r "${GRUBCFG_TEMPLATE}" ] ; then
+          log    "Secure Boot template for GRUB [${GRUBCFG_TEMPLATE}] not found."
+          eerror "Secure Boot template for GRUB [${GRUBCFG_TEMPLATE}] not found." ; eend 1
+          bailout 54
+        fi
+
+        cp "${GRUBCFG_TEMPLATE}" "${GRUBCFG_TMP}"
+        adjust_boot_files "${GRUBCFG_TMP}"
+
+        mmd -i "${CHROOT_OUTPUT}/${EFI_IMG}" ::EFI/ubuntu || bailout 55
+        mcopy -i "${CHROOT_OUTPUT}/${EFI_IMG}" "${GRUBCFG_TMP}" ::EFI/ubuntu/grub.cfg || bailout 56
+        rm "${GRUBCFG_TMP}"
+
+        mcopy -i "${CHROOT_OUTPUT}/${EFI_IMG}" "${TEMPLATE_DIRECTORY}"/EFI/BOOT/grubx64.efi.signed ::EFI/BOOT/grubx64.efi >/dev/null || bailout 57
+        mcopy -i "${CHROOT_OUTPUT}/${EFI_IMG}" "${TEMPLATE_DIRECTORY}"/EFI/BOOT/shimx64.efi.signed ::EFI/BOOT/bootx64.efi >/dev/null || bailout 58
+
+        log   "Generated 64-bit Secure Boot (ubuntu) EFI image ${CHROOT_OUTPUT}/${EFI_IMG}"
+        einfo "Generated 64-bit Secure Boot (ubuntu) EFI image ${CHROOT_OUTPUT}/${EFI_IMG}" ; eend 0
+      fi
+    fi
+  fi
+
+  if [[ "$ARCH" == "i386" ]] ; then
+    if ! [ -r "${CHROOT_OUTPUT}/${BOOTX32}" ] ; then
+      log    "Can not access GRUB efi image ${CHROOT_OUTPUT}/${BOOTX32}."
+      eerror "Can not access GRUB efi image ${CHROOT_OUTPUT}/${BOOTX32}." ; eend 1
+      log    "Possible reason is failure to run ${GRML_FAI_CONFIG}/config/scripts/GRMLBASE/45-grub-images"
+      ewarn "Possible reason is failure to run ${GRML_FAI_CONFIG}/config/scripts/GRMLBASE/45-grub-images"
+      bailout 50
+    fi
+
+    dd if=/dev/zero of="${CHROOT_OUTPUT}/${EFI_IMG}" bs=4M count=1 2>/dev/null || bailout 50
+    mkfs.vfat -n GRML "${CHROOT_OUTPUT}/${EFI_IMG}" >/dev/null || bailout 51
+    mmd -i "${CHROOT_OUTPUT}/${EFI_IMG}" ::EFI || bailout 52
+    mmd -i "${CHROOT_OUTPUT}/${EFI_IMG}" ::EFI/BOOT || bailout 52
+    mcopy -i "${CHROOT_OUTPUT}/${EFI_IMG}" "${CHROOT_OUTPUT}/${BOOTX32}" ::EFI/BOOT/bootia32.efi >/dev/null || bailout 53
+    log   "Generated 32-bit EFI image $BOOTX32"
+    einfo "Generated 32-bit EFI image $BOOTX32" ; eend 0
+  fi
+}
+# }}}
+
 # BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
@@ -857,335 +969,315 @@ mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for s
 # prepare ISO
 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
   if [ -n "$BOOTSTRAP_ONLY" ] ; then
-     log   "Skipping stage 'boot' as building with bootstrap only."
-     ewarn "Skipping stage 'boot' as building with bootstrap only." ; eend 0
+    log   "Skipping stage 'boot' as building with bootstrap only."
+    ewarn "Skipping stage 'boot' as building with bootstrap only." ; eend 0
   else
-    if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
-       log   "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
-       ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
+    # booting stuff:
+    mkdir -p "$BUILD_OUTPUT"/boot/isolinux
+    mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
+
+    # if we don't have an initrd we a) can't boot and b) there was an error
+    # during build, so check for the file:
+    INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
+    if [ -n "$INITRD" ] ; then
+      cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.img
+      find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
     else
-       # booting stuff:
-       [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
-       [ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
-
-       # if we don't have an initrd we a) can't boot and b) there was an error
-       # during build, so check for the file:
-       INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
-       if [ -n "$INITRD" ] ; then
-          cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.img
-          find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
-       else
-          log    "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
-          eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
-          bailout 10
-       fi
-
-       KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
-       if [ -n "$KERNEL_IMAGE" ] ; then
-          cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/vmlinuz
-       else
-          log    "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
-          eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
-          bailout 11
-       fi
-
-       # EFI boot files
-       if [ -r "${CHROOT_OUTPUT}/boot/efi.img" -a -r "${CHROOT_OUTPUT}/boot/bootx64.efi" ] ; then
-         einfo "Moving 64-bit EFI boot files into ISO path."
-         log "Moving 64-bit EFI boot files into ISO path."
-         RC=$0
-         mv "${CHROOT_OUTPUT}/boot/efi.img" "${BUILD_OUTPUT}/boot/" || RC=$?
-         mkdir -p "${BUILD_OUTPUT}/efi/boot/" || RC=$?
-         mv "${CHROOT_OUTPUT}/boot/bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi" || RC=$?
-         eend $?
-       elif [ -r "${CHROOT_OUTPUT}/boot/efi.img" -a -r "${CHROOT_OUTPUT}/boot/bootia32.efi" ] ; then
-         einfo "Moving 32-bit EFI boot files into ISO path."
-         log "Moving 32-bit EFI boot files into ISO path."
-         RC=$0
-         mv "${CHROOT_OUTPUT}/boot/efi.img" "${BUILD_OUTPUT}/boot/" || RC=$?
-         mkdir -p "${BUILD_OUTPUT}/efi/boot/" || RC=$?
-         mv "${CHROOT_OUTPUT}/boot/bootia32.efi" "${BUILD_OUTPUT}/efi/boot/bootia32.efi" || RC=$?
-         eend $?
-       else
-         ewarn "No EFI boot files found, skipping." ; eend 0
-       fi
+      log    "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
+      eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
+      bailout 10
+    fi
 
-       [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
-       if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
-          log    "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
-          eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
-          bailout 8
-       fi
+    KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
+    if [ -n "$KERNEL_IMAGE" ] ; then
+      cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/vmlinuz
+    else
+      log    "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
+      eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
+      bailout 11
+    fi
 
-       # copy _required_ isolinux files
-       if [ -d "${CHROOT_OUTPUT}/usr/lib/ISOLINUX" ] ; then
-         copy_addon_file isolinux.bin /usr/lib/ISOLINUX isolinux
-         for file in ${CHROOT_OUTPUT}/usr/lib/syslinux/modules/bios/*.c32 ; do
-           copy_addon_file "$(basename "$file")"  /usr/lib/syslinux/modules/bios/ isolinux
-         done
-       else # syslinux versions <= 3:4.05+dfsg-6+deb8u1
-         copy_addon_file isolinux.bin /usr/lib/syslinux isolinux
-         copy_addon_file ifcpu64.c32  /usr/lib/syslinux isolinux
-         copy_addon_file vesamenu.c32 /usr/lib/syslinux isolinux
-       fi
+    # we need to set "$BOOTID" before we invoke adjust_boot_files for the
+    # first time, being inside grub_setup below
+    if [ -n "$NO_BOOTID" ] ; then
+      log   'Skipping bootid feature as requested via $NO_BOOTID.'
+      einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
+    else
+      [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
+      mkdir -p "$BUILD_OUTPUT"/conf
+      einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
+      log   "Generating /conf/bootid.txt with entry ${BOOTID}."
+      echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
+      eend $?
+    fi
 
-       # *always* copy files to output directory so the variables
-       # get adjusted according to the build.
-       cp ${TEMPLATE_DIRECTORY}/boot/isolinux/*  "$BUILD_OUTPUT"/boot/isolinux/
+    grub_setup
+
+    # EFI boot files
+    if [ -r "${CHROOT_OUTPUT}/boot/efi.img" -a -r "${CHROOT_OUTPUT}/boot/bootx64.efi" ] ; then
+      einfo "Copying 64-bit EFI boot files into ISO path."
+      log   "Copying 64-bit EFI boot files into ISO path."
+      RC=$0
+      cp "${CHROOT_OUTPUT}/boot/efi.img" "${BUILD_OUTPUT}/boot/" || RC=$?
+      mkdir -p "${BUILD_OUTPUT}/EFI/BOOT/" || RC=$?
+      cp "${CHROOT_OUTPUT}/boot/bootx64.efi" "${BUILD_OUTPUT}/EFI/BOOT/bootx64.efi" || RC=$?
+      eend $?
+    elif [ -r "${CHROOT_OUTPUT}/boot/efi.img" -a -r "${CHROOT_OUTPUT}/boot/bootia32.efi" ] ; then
+      einfo "Copying 32-bit EFI boot files into ISO path."
+      log "Copying 32-bit EFI boot files into ISO path."
+      RC=$0
+      cp "${CHROOT_OUTPUT}/boot/efi.img" "${BUILD_OUTPUT}/boot/" || RC=$?
+      mkdir -p "${BUILD_OUTPUT}/EFI/BOOT/" || RC=$?
+      cp "${CHROOT_OUTPUT}/boot/bootia32.efi" "${BUILD_OUTPUT}/EFI/BOOT/bootia32.efi" || RC=$?
+      eend $?
+    else
+      ewarn "No EFI boot files found, skipping." ; eend 0
+    fi
 
-       mkdir -p "${BUILD_OUTPUT}/boot/grub"
-       cp -a ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
+    [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
+    if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
+      log    "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
+      eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
+      bailout 8
+    fi
 
-       if [ -n "$NO_ADDONS" ] ; then
-          rm -f "$BUILD_OUTPUT"/boot/grub/addons.cfg
-          log   "Skipping installation of boot addons as requested via \$NO_ADDONS."
-          einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
-       else
-          if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
-            log   "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
-            ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
-          else
-            # copy addons from system packages or grml-live-addons
-            copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
-            copy_addon_file pci.ids /usr/share/misc addons
-            copy_addon_file memtest86+.bin /boot addons
-
-            # since syslinux(-common) v3:6.03~pre1+dfsg-4 the files are in a
-            # different directory :(
-            if [ -d "${CHROOT_OUTPUT}/usr/lib/syslinux/modules/bios/" ] ; then
-              syslinux_modules_dir=/usr/lib/syslinux/modules/bios/
-            else
-              syslinux_modules_dir=/usr/lib/syslinux
-            fi
-            for file in chain.c32 hdt.c32 mboot.c32 menu.c32; do
-              copy_addon_file "${file}" "${syslinux_modules_dir}" addons
-            done
-
-            copy_addon_file memdisk /usr/lib/syslinux addons
-
-            # make memtest filename FAT16/8.3 compatible
-            mv "${BUILD_OUTPUT}/boot/addons/memtest86+.bin" \
-              "${BUILD_OUTPUT}/boot/addons/memtest"
-
-            # copy only files so we can handle bsd4grml on its own
-            for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
-              test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
-            done
-
-            if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
-               log   "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
-               einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
-            else
-               if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
-                 cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
-               else
-                 log   "Missing addon file: bsd4grml"
-                 ewarn "Missing addon file: bsd4grml" ; eend 0
-               fi
-            fi
-
-          fi # no "$TEMPLATE_DIRECTORY"/boot/addons
-       fi # NO_ADDONS
-
-       # generate loopback.cfg config file without depending on grub's regexp module
-       # which isn't available in Debian/squeeze
-       echo "## grub2 loopback configuration" > "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
-       echo "source /boot/grub/header.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
-       for config in "${BUILD_OUTPUT}"/boot/grub/*_default.cfg "${BUILD_OUTPUT}"/boot/grub/*_options.cfg ; do
-         [ -r "$config" ] || continue
-         echo "source ${config##$BUILD_OUTPUT}" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
-       done
-       if [ -z "$NO_ADDONS" ] ; then
-         echo "source /boot/grub/addons.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
-       fi
-       echo "source /boot/grub/footer.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
-
-       # copy grub files from target
-       mkdir -p "${BUILD_OUTPUT}"/boot/grub/i386-pc/
-       cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/i386-pc/
-       cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/i386-pc/
-       cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/i386-pc/
-       cp -a "${CHROOT_OUTPUT}"/usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/
-       cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/
-       cp -a "${CHROOT_OUTPUT}"/boot/grub/grub.img "${BUILD_OUTPUT}"/boot/grub/
-
-       # copy modules for UEFI grub, 64-bit
-       mkdir -p "${BUILD_OUTPUT}"/boot/grub/x86_64-efi/
-       cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/x86_64-efi/*.{mod,lst} "${BUILD_OUTPUT}"/boot/grub/x86_64-efi/
-
-       # copy modules for UEFI grub, 32-bit
-       mkdir -p "${BUILD_OUTPUT}"/boot/grub/i386-efi/
-       cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/i386-efi/*.{mod,lst} "${BUILD_OUTPUT}"/boot/grub/i386-efi/
-
-       if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
-          log    "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
-          eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
-          bailout 9
-       fi
+    # copy _required_ isolinux files
+    if [ -d "${CHROOT_OUTPUT}/usr/lib/ISOLINUX" ] ; then
+      copy_addon_file isolinux.bin /usr/lib/ISOLINUX isolinux
+      for file in ${CHROOT_OUTPUT}/usr/lib/syslinux/modules/bios/*.c32 ; do
+        copy_addon_file "$(basename "$file")"  /usr/lib/syslinux/modules/bios/ isolinux
+      done
+    else # syslinux versions <= 3:4.05+dfsg-6+deb8u1
+      copy_addon_file isolinux.bin /usr/lib/syslinux isolinux
+      copy_addon_file ifcpu64.c32  /usr/lib/syslinux isolinux
+      copy_addon_file vesamenu.c32 /usr/lib/syslinux isolinux
+    fi
 
-       mkdir -p "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
-       cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
+    # *always* copy files to output directory so the variables
+    # get adjusted according to the build.
+    cp ${TEMPLATE_DIRECTORY}/boot/isolinux/*  "$BUILD_OUTPUT"/boot/isolinux/
 
-       # adjust boot splash information:
-       RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
-       RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
-       RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
+    mkdir -p "${BUILD_OUTPUT}/boot/grub"
+    cp -a ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
 
-       if [ -r "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version ] ; then
-          sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
-          sed -i "s/%DATE%/$DATE/"                                      "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
-       fi
+    if [ -n "$NO_ADDONS" ] ; then
+      rm -f "$BUILD_OUTPUT"/boot/grub/addons.cfg
+      log   "Skipping installation of boot addons as requested via \$NO_ADDONS."
+      einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
+    else
+      if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
+        log   "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
+        ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
+      else
+        # copy addons from system packages or grml-live-addons
+        copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
+        copy_addon_file pci.ids /usr/share/misc addons
+        copy_addon_file memtest86+.bin /boot addons
+
+        # since syslinux(-common) v3:6.03~pre1+dfsg-4 the files are in a
+        # different directory :(
+        if [ -d "${CHROOT_OUTPUT}/usr/lib/syslinux/modules/bios/" ] ; then
+          syslinux_modules_dir=/usr/lib/syslinux/modules/bios/
+        else
+          syslinux_modules_dir=/usr/lib/syslinux
+        fi
+        for file in chain.c32 hdt.c32 mboot.c32 menu.c32; do
+          copy_addon_file "${file}" "${syslinux_modules_dir}" addons
+        done
 
-       # make sure the squashfs filename is set accordingly:
-       SQUASHFS_NAME="$GRML_NAME.squashfs"
+        copy_addon_file memdisk /usr/lib/syslinux addons
 
-       if [ -n "$NO_BOOTID" ] ; then
-          log   'Skipping bootid feature as requested via $NO_BOOTID.'
-          einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
-       else
-          [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
-          [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
-          einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
-          log   "Generating /conf/bootid.txt with entry ${BOOTID}."
-          echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
-          eend $?
-       fi
+        # make memtest filename FAT16/8.3 compatible
+        mv "${BUILD_OUTPUT}/boot/addons/memtest86+.bin" \
+          "${BUILD_OUTPUT}/boot/addons/memtest"
 
-       # adjust all variables in the templates with the according distribution information
-       for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
-                   "${BUILD_OUTPUT}"/boot/grub/* ; do
-         if [ -r "${file}" ] && [ -f "${file}" ] ; then
-           sed -i "s/%ARCH%/$ARCH/g"                    "${file}"
-           sed -i "s/%DATE%/$DATE/g"                    "${file}"
-           sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g"      "${file}"
-           sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g"      "${file}"
-           sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g"  "${file}"
-           sed -i "s/%GRML_NAME%/$GRML_NAME/g"          "${file}"
-           sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g"  "${file}"
-           sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g"    "${file}"
-           sed -i "s/%SHORT_NAME%/$SHORT_NAME/g"        "${file}"
-           sed -i "s/%VERSION%/$VERSION/g"              "${file}"
-
-           [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s; boot=live; boot=live $DEFAULT_BOOTOPTIONS;"  "${file}"
-
-           if [ -n "$NO_BOOTID" ] ; then
-              sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
-           else
-              sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
-           fi
-         fi
-       done
-
-       for param in ARCH DATE DISTRI_INFO DISTRI_NAME DISTRI_SPLASH GRML_NAME SQUASHFS_NAME \
-           RELEASE_INFO SHORT_NAME VERSION ; do
-           for file in $(find "${BUILD_OUTPUT}" -name "*%$param%*") ; do
-               value="$(eval echo '$'"$param")"
-               mv ${file} ${file/\%${param}\%/$value}
-           done
-       done
-
-       # adjust bootsplash accordingly but make sure the string has the according lenght
-       SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
-       SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
-       for file in f4 f5 ; do
-          if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
-             sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
-             sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
-          fi
-       done
-
-       # generate addon list
-       rm -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
-       for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
-         include_name=$(basename "$name")
-         echo "include $include_name"  >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
-       done
-
-       if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
-          log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-          echo "include grmlmain.cfg"    >  "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-          echo "include default.cfg"     >  "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-          echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-          echo "include grml.cfg"        >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-
-          for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
-            echo "include $(basename $f)"     >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-          done
-
-          echo "include options.cfg"     >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-          if [ -z "$NO_ADDONS" ] ; then
-            echo "include addons.cfg"    >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-          fi
-          echo "include isoprompt.cfg"   >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-          echo "include hd.cfg"          >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-          echo "include hidden.cfg"      >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-       else # assume we are building a custom distribution:
-          log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
-          einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
-          if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
-            log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
-            eindent
-            einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
-            eoutdent
-            eend $?
-         else
-            log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-            echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-            if [ -z "$NO_ADDONS" ] ; then
-              echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-            fi
-          fi
-       fi
+        # copy only files so we can handle bsd4grml on its own
+        for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
+          test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
+        done
 
-       # use old style console based isolinux method only if requested:
-       if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
-          log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
-          einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
-          if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
-            einfo "include for console.cfg already found, nothing to do."
-            eend 0
-          else
-            log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
-            einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
-            echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
-            eend $?
-          fi
-       else
-          log 'Using graphical boot menu.'
-          if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
-            log "include for vesamenu.cfg already found, nothing to do."
+        if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
+          log   "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
+          einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
+        else
+          if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
+            cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
           else
-            log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
-            echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+            log   "Missing addon file: bsd4grml"
+            ewarn "Missing addon file: bsd4grml" ; eend 0
           fi
-       fi
+        fi
 
-       if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
-          sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
-       fi
+      fi # no "$TEMPLATE_DIRECTORY"/boot/addons
+    fi # NO_ADDONS
+
+    # generate loopback.cfg config file without depending on grub's regexp module
+    # which isn't available in Debian/squeeze
+    echo "## grub2 loopback configuration" > "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+    echo "source /boot/grub/header.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+    for config in "${BUILD_OUTPUT}"/boot/grub/*_default.cfg "${BUILD_OUTPUT}"/boot/grub/*_options.cfg ; do
+      [ -r "$config" ] || continue
+      echo "source ${config##$BUILD_OUTPUT}" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+    done
+    if [ -z "$NO_ADDONS" ] ; then
+      echo "source /boot/grub/addons.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+    fi
+    echo "source /boot/grub/footer.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+
+    # copy grub files from target
+    mkdir -p "${BUILD_OUTPUT}"/boot/grub/i386-pc/
+    cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/i386-pc/
+    cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/i386-pc/
+    cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/i386-pc/
+    cp -a "${CHROOT_OUTPUT}"/usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/
+    cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/
+    cp -a "${CHROOT_OUTPUT}"/boot/grub/grub.img "${BUILD_OUTPUT}"/boot/grub/
+
+    # copy modules for UEFI grub, 64-bit
+    mkdir -p "${BUILD_OUTPUT}"/boot/grub/x86_64-efi/
+    cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/x86_64-efi/*.{mod,lst} "${BUILD_OUTPUT}"/boot/grub/x86_64-efi/
+
+    # copy modules for UEFI grub, 32-bit
+    mkdir -p "${BUILD_OUTPUT}"/boot/grub/i386-efi/
+    cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/i386-efi/*.{mod,lst} "${BUILD_OUTPUT}"/boot/grub/i386-efi/
+
+    if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
+      log    "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
+      eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
+      bailout 9
+    fi
 
-       DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
-       if ! [ -r "$DPKG_LIST" ] ; then
-          ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
-       else
-          einfo "Storing package list information as /GRML/${GRML_NAME}/packages.txt on ISO."
-          cp "$DPKG_LIST" "${BUILD_OUTPUT}"/GRML/"${GRML_NAME}"/packages.txt
-          eend $?
-       fi
+    mkdir -p "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
+    cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
 
-       # autostart for Windows:
-       if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
-          cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
-       fi
+    # adjust boot splash information:
+    RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
+    RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
+    RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
+
+    if [ -r "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version ] ; then
+      sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
+      sed -i "s/%DATE%/$DATE/"                                      "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
+    fi
+
+    # make sure the squashfs filename is set accordingly:
+    SQUASHFS_NAME="$GRML_NAME.squashfs"
+
+    # adjust all variables in the templates with the according distribution information
+    adjust_boot_files "${BUILD_OUTPUT}"/boot/isolinux/*.cfg \
+      "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
+      "${BUILD_OUTPUT}"/boot/grub/* \
+      "${BUILD_OUTPUT}"/boot/ubuntu/*
+
+    for param in ARCH DATE DISTRI_INFO DISTRI_NAME DISTRI_SPLASH GRML_NAME SQUASHFS_NAME \
+      RELEASE_INFO SHORT_NAME VERSION ; do
+      for file in $(find "${BUILD_OUTPUT}" -name "*%$param%*") ; do
+        value="$(eval echo '$'"$param")"
+        mv ${file} ${file/\%${param}\%/$value}
+      done
+    done
+
+    # adjust bootsplash accordingly but make sure the string has the according length
+    SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
+    SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
+    for file in f4 f5 ; do
+      if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
+        sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
+        sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
+      fi
+    done
+
+    # generate addon list
+    rm -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
+    for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
+      include_name=$(basename "$name")
+      echo "include $include_name"  >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
+    done
+
+    if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
+      log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+      echo "include grmlmain.cfg"    >  "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+      echo "include default.cfg"     >  "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+      echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+      echo "include grml.cfg"        >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+
+      for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
+        echo "include $(basename $f)"     >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+      done
+
+      echo "include options.cfg"     >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+      if [ -z "$NO_ADDONS" ] ; then
+        echo "include addons.cfg"    >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+      fi
+      echo "include isoprompt.cfg"   >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+      echo "include hd.cfg"          >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+      echo "include hidden.cfg"      >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+    else # assume we are building a custom distribution:
+      log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
+      einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
+      if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
+        log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
+        eindent
+        einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
+        eoutdent
+        eend $?
+      else
+        log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+        echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+        if [ -z "$NO_ADDONS" ] ; then
+          echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+        fi
+      fi
+    fi
+
+    # use old style console based isolinux method only if requested:
+    if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
+      log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
+      einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
+      if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
+        einfo "include for console.cfg already found, nothing to do."
+        eend 0
+      else
+        log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+        einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+        echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+        eend $?
+      fi
+    else
+      log 'Using graphical boot menu.'
+      if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
+        log "include for vesamenu.cfg already found, nothing to do."
+      else
+        log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+        echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+      fi
+    fi
+
+    if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
+      sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
+    fi
+
+    DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
+    if ! [ -r "$DPKG_LIST" ] ; then
+      ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
+    else
+      einfo "Storing package list information as /GRML/${GRML_NAME}/packages.txt on ISO."
+      cp "$DPKG_LIST" "${BUILD_OUTPUT}"/GRML/"${GRML_NAME}"/packages.txt
+      eend $?
+    fi
+
+    # autostart for Windows:
+    if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
+      cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
+    fi
 
     FORCE_ISO_REBUILD=true
     einfo "Finished execution of stage 'boot'" ; eend 0
-    fi
   fi # BOOTSTRAP_ONLY
 else
-   log    'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
-   eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
-   bailout
+  log    'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
+  eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
+  bailout
 fi
 
 # support installation of local files into the chroot/ISO
diff --git a/templates/EFI/BOOT/README b/templates/EFI/BOOT/README
new file mode 100644 (file)
index 0000000..41ad10f
--- /dev/null
@@ -0,0 +1,3 @@
+# ubuntu approach:
+shimx64.efi.signed = /usr/lib/shim/shimx64.efi.signed                   from http://de.archive.ubuntu.com/ubuntu/pool/main/s/shim-signed/shim-signed_1.32~17.04.1+0.9+1474479173.6c180c6-1ubuntu1_amd64.deb
+grubx64.efi.signed = /usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed from http://de.archive.ubuntu.com/ubuntu/pool/main/g/grub2-signed/grub-efi-amd64-signed_1.80.2+2.02~beta3-4ubuntu2.2_amd64.deb
diff --git a/templates/EFI/BOOT/grubx64.efi.signed b/templates/EFI/BOOT/grubx64.efi.signed
new file mode 100644 (file)
index 0000000..7c31b00
Binary files /dev/null and b/templates/EFI/BOOT/grubx64.efi.signed differ
diff --git a/templates/EFI/BOOT/shimx64.efi.signed b/templates/EFI/BOOT/shimx64.efi.signed
new file mode 100644 (file)
index 0000000..9943e7a
Binary files /dev/null and b/templates/EFI/BOOT/shimx64.efi.signed differ
diff --git a/templates/EFI/ubuntu/grub.cfg b/templates/EFI/ubuntu/grub.cfg
new file mode 100644 (file)
index 0000000..ec350b4
--- /dev/null
@@ -0,0 +1,4 @@
+# if we end up here it should mean we have EFI but not with Secure Boot enabled,
+# so source our main (and common) GRUB configuration instead
+set prefix=($root)/boot/grub/
+configfile /boot/grub/grub.cfg
diff --git a/templates/boot/grub/grmlenv.cfg b/templates/boot/grub/grmlenv.cfg
new file mode 100644 (file)
index 0000000..fe779ee
--- /dev/null
@@ -0,0 +1,11 @@
+# this is a simple test to identify whether it looks like the Secure Boot enabled/signed
+# GRUB is running or if it's a full featured GRUB version, the former doesn't allow running cpuid
+if cpuid ; then
+  echo "It looks like Secure Boot is NOT enabled."
+  set grml_secureboot=false
+  export grml_secureboot
+else
+  echo "It looks like Secure Boot is enabled."
+  set grml_secureboot=true
+  export grml_secureboot
+fi
diff --git a/templates/secureboot/grub.cfg b/templates/secureboot/grub.cfg
new file mode 100644 (file)
index 0000000..b378aab
--- /dev/null
@@ -0,0 +1,112 @@
+set grml_orig_prefix=$prefix
+export grml_orig_prefix
+set grml_orig_root=$root
+export grml_orig_root
+
+set prefix=(hd0)/boot/grub/
+set root=(hd0)
+source (hd0)/boot/grub/grmlenv.cfg
+set prefix=(hd0)/boot/grub/
+
+if [ "$grml_secureboot" = false ] ; then
+  set root=(hd0)
+  configfile /boot/grub/grub.cfg
+else
+  set prefix=$grml_orig_prefix
+  set root=$grml_orig_root
+
+  set timeout=20
+  set root=(hd0)
+
+  # this is basically a copy of templates/boot/grub/header.cfg but to avoid
+  # failures due to Secure Boot restrictions and sourcing addons.cfg via
+  # /boot/grub/loopback.cfg (and then showing entries that are at the wrong
+  # position as well as don't work at all) we have to specify the appropriate
+  # config here
+  if loadfont /boot/grub/ascii.pf2 ; then
+    set gfxmode=auto
+    insmod efi_gop
+    insmod efi_uga
+    insmod gfxterm
+    insmod png
+    # this is forbidden to be loaded under Secure Boot:
+    #insmod vbe
+    terminal_output gfxterm
+  fi
+
+  if [ -f /boot/grub/%GRML_NAME%-theme/theme.txt ] ; then
+    set theme=/boot/grub/%GRML_NAME%-theme/theme.txt
+    export theme
+  elif [ -f /boot/grub/grml-theme/theme.txt ] ; then
+    set theme=/boot/grub/grml-theme/theme.txt
+    export theme
+  else
+    set menu_color_normal=white/black
+    set menu_color_highlight=black/light-gray
+    set color_normal=white/black
+  fi
+
+  menuentry "Boot %GRML_NAME% in normal mode (release %VERSION%, Secure Boot enabled)" {
+      set gfxpayload=keep
+      echo 'Loading kernel...'
+      linux   /boot/%SHORT_NAME%/vmlinuz apm=power-off boot=live live-media-path=/live/%GRML_NAME%/ bootid=%BOOTID% "${loopback}" "${kernelopts}" nomce net.ifnames=0 
+      echo 'Loading initrd...'
+      initrd  /boot/%SHORT_NAME%/initrd.img
+  }
+
+  menuentry "Boot %GRML_NAME% - enable persistency" {
+      set gfxpayload=keep
+      echo 'Loading kernel...'
+      linux   /boot/%SHORT_NAME%/vmlinuz apm=power-off boot=live live-media-path=/live/%GRML_NAME%/ bootid=%BOOTID% "${loopback}" "${kernelopts}" nomce net.ifnames=0 persistence 
+      echo 'Loading initrd...'
+      initrd  /boot/%SHORT_NAME%/initrd.img
+  }
+
+  menuentry "Boot %GRML_NAME% - copy %GRML_NAME% to RAM" {
+      set gfxpayload=keep
+      echo 'Loading kernel...'
+      linux   /boot/%SHORT_NAME%/vmlinuz apm=power-off boot=live live-media-path=/live/%GRML_NAME%/ bootid=%BOOTID% "${loopback}" "${kernelopts}" nomce net.ifnames=0 toram=%GRML_NAME%.squashfs 
+      echo 'Loading initrd...'
+      initrd  /boot/%SHORT_NAME%/initrd.img
+  }
+
+  menuentry "Boot %GRML_NAME% - copy whole medium to RAM" {
+      set gfxpayload=keep
+      echo 'Loading kernel...'
+      linux   /boot/%SHORT_NAME%/vmlinuz apm=power-off boot=live live-media-path=/live/%GRML_NAME%/ bootid=%BOOTID% "${loopback}" "${kernelopts}" nomce net.ifnames=0 toram 
+      echo 'Loading initrd...'
+      initrd  /boot/%SHORT_NAME%/initrd.img
+  }
+
+  menuentry "Boot %GRML_NAME% - disable framebuffer/kernel mode setting" {
+      set gfxpayload=keep
+      echo 'Loading kernel...'
+      linux   /boot/%SHORT_NAME%/vmlinuz apm=power-off boot=live live-media-path=/live/%GRML_NAME%/ bootid=%BOOTID% "${loopback}" "${kernelopts}" nomce net.ifnames=0 video=vesafb:off cirrus.modeset=0 i915.modeset=0 mgag200.modeset=0 nomodeset nouveau.modeset=0 radeon.modeset=0 
+      echo 'Loading initrd...'
+      initrd  /boot/%SHORT_NAME%/initrd.img
+  }
+
+  menuentry "Boot %GRML_NAME% - enable forensic mode" {
+      set gfxpayload=keep
+      echo 'Loading kernel...'
+      linux   /boot/%SHORT_NAME%/vmlinuz apm=power-off boot=live live-media-path=/live/%GRML_NAME%/ bootid=%BOOTID% "${loopback}" "${kernelopts}" nomce net.ifnames=0 read-only nofstab noraid nodmraid nolvm noautoconfig noswap raid=noautodetect 
+      echo 'Loading initrd...'
+      initrd  /boot/%SHORT_NAME%/initrd.img
+  }
+
+  menuentry "Boot %GRML_NAME% - enable serial console" {
+      set gfxpayload=keep
+      echo 'Loading kernel...'
+      linux   /boot/%SHORT_NAME%/vmlinuz apm=power-off boot=live live-media-path=/live/%GRML_NAME%/ bootid=%BOOTID% "${loopback}" "${kernelopts}" nomce net.ifnames=0 video=vesafb:off console=tty1 console=ttyS0,9600n8 
+      echo 'Loading initrd...'
+      initrd  /boot/%SHORT_NAME%/initrd.img
+  }
+
+  menuentry "Boot %GRML_NAME% - debug mode" {
+      set gfxpayload=keep
+      echo 'Loading kernel...'
+      linux   /boot/%SHORT_NAME%/vmlinuz apm=power-off boot=live live-media-path=/live/%GRML_NAME%/ bootid=%BOOTID% "${loopback}" "${kernelopts}" nomce net.ifnames=0 initcall verbose debug=vc systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M 
+      echo 'Loading initrd...'
+      initrd  /boot/%SHORT_NAME%/initrd.img
+  }
+fi