When installing to a system using the GRUB payload from coreboot it's not necessary to install GRUB, only the configuration file. Projects like Libreboot and Autoboot exploit this to load systems from encrypted partitions using their own GRUB install, a configuration that would previously cause install failures. This is accomplished by adding a platform flag to grub-configuration the system can now specify which environment GRUB is being installed to and adjust appropriately. The old behaviour is used when the field is set to 'bios. When the new behaviour is set to 'coreboot, grub.cfg is copied to /boot/grub/coreboot_grub.cfg. Symlinks are created for /boot/grub/libreboot_grub.cfg and /boot/grub/autoboot_grub.cfg to maintain compatibility with older releases of Libreboot and Autoboot respectively, though these are subject to removal and aren't promised in the documentation. The platform field is respected when building a virtual machine, allowing for Guix to be run using Libreboot BIOS in QEMU. * doc/guix.texi (GRUB Configuration): Explain platform field and its behaviour. * gnu/system/grub.scm (): Add platform field. * gnu/build/install.scm (install-grub): Depending on platform, either install GRUB or copy and link grub.cfg to various locations. --- doc/guix.texi | 15 ++++++++++++++- gnu/build/install.scm | 45 ++++++++++++++++++++++++++++++--------------- gnu/system/grub.scm | 6 +++++- 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 51b0652..e728c5d 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -16,7 +16,8 @@ Copyright @copyright{} 2013 Nikita Karetnikov@* Copyright @copyright{} 2015 Mathieu Lirzin@* Copyright @copyright{} 2014 Pierre-Antoine Rault@* Copyright @copyright{} 2015 Taylan Ulrich Bayırlı/Kammer@* -Copyright @copyright{} 2015, 2016 Leo Famulari +Copyright @copyright{} 2015, 2016 Leo Famulari@* +Copyright @copyright{} 2016 Jookia Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -9270,6 +9271,18 @@ understood by the @command{grub-install} command, such as @code{/dev/sda} or @code{(hd0)} (@pxref{Invoking grub-install,,, grub, GNU GRUB Manual}). +@item @code{platform} (default: @code{'bios}) +This is a symbol that specifies how GRUB is to be installed. + +When it is the symbol @code{'bios} GRUB itself as well as its configuration are +installed to @code{/boot/grub} then loaded using a small shim placed at the +the first sector of @code{device} to be loaded by most traditional BIOSes. + +When the symbol is @code{'coreboot} a configuration intended for use by +coreboot's GRUB payload will be copied to @code{/boot/grub/coreboot_grub.cfg}. +If using this with Libreboot's or Autoboot's GRUB payload this file should be +automatically found and chainloaded when booting, even inside encrypted disks. + @item @code{menu-entries} (default: @code{()}) A possibly empty list of @code{menu-entry} objects (see below), denoting entries to appear in the GRUB boot menu, in addition to the current diff --git a/gnu/build/install.scm b/gnu/build/install.scm index b28dea8..4aad04d 100644 --- a/gnu/build/install.scm +++ b/gnu/build/install.scm @@ -36,24 +36,39 @@ ;;; ;;; Code: -(define* (install-grub grub.cfg device mount-point) - "Install GRUB with GRUB.CFG on DEVICE, which is assumed to be mounted on -MOUNT-POINT." - (let* ((target (string-append mount-point "/boot/grub/grub.cfg")) - (pivot (string-append target ".new")) - (gcroot "/var/guix/gcroots")) - (mkdir-p (dirname target)) +(define* (install-grub grub.cfg device mount-point platform) + "Install GRUB with GRUB.CFG on DEVICE. PLATFORM determines the installation +method. MOUNT-POINT should contain the root file system." + (let* ((grubdir (string-append mount-point "/boot/grub")) + (tmpcfg (string-append grubdir "/grub.tmp")) + (gcroot "/var/guix/gcroots")) + (mkdir-p grubdir) ;; Copy GRUB.CFG instead of just symlinking it, because symlinks won't ;; work when /boot is on a separate partition. Do that atomically. - (copy-file grub.cfg pivot) - (rename-file pivot target) - - (unless (zero? (system* "grub-install" "--no-floppy" - "--boot-directory" - (string-append mount-point "/boot") - device)) - (error "failed to install GRUB")) + (copy-file grub.cfg tmpcfg) + + (cond ((eq? 'bios platform) + (begin + (rename-file tmpcfg (string-append grubdir "/grub.cfg")) + (unless (zero? (system* "grub-install" + "--no-floppy" + "--boot-directory" + (string-append mount-point "/boot") + device)) + (error "failed to install GRUB")))) + ((eq? 'coreboot platform) + ;; XXX: Replace this with a single copy once Libreboot and Autoboot + ;; have a stable release reading coreboot_grub.cfg. For now, use + ;; relative symlinks so GRUB can find it. + (let ((my-config (lambda (name) + (string-append grubdir "/" name "_grub.cfg")))) + (rename-file tmpcfg (my-config "coreboot")) + (false-if-exception ; No matter if these fail. + ((symlink "./coreboot_grub.cfg" (my-config "libreboot")) + (symlink "./coreboot_grub.cfg" (my-config "autoboot")))))) + (#t + (error "Unrecognized GRUB platform!"))) ;; Register GRUB.CFG as a GC root so the fonts, background images, etc. ;; referred to by GRUB.CFG are not GC'd. diff --git a/gnu/system/grub.scm b/gnu/system/grub.scm index c9d4359..4808c0e 100644 --- a/gnu/system/grub.scm +++ b/gnu/system/grub.scm @@ -52,6 +52,7 @@ grub-configuration grub-configuration? grub-configuration-device + grub-configuration-platform menu-entry menu-entry? @@ -101,6 +102,8 @@ (grub grub-configuration-grub ; package (default (@ (gnu packages grub) grub))) (device grub-configuration-device) ; string + (platform grub-configuration-platform ; 'bios | 'coreboot + (default 'bios)) (menu-entries grub-configuration-menu-entries ; list (default '())) (default-entry grub-configuration-default-entry ; integer @@ -298,6 +301,7 @@ submenu \"GNU system, old configurations...\" {~%") (false-if-exception (install-grub ,grub.cfg ,(grub-configuration-device config) - ,mount-point)))) + ,mount-point + (quote ,(grub-configuration-platform config)))))) ;;; grub.scm ends here -- 2.7.0