diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scm index 65d7171432..4f18c9b518 100644 --- a/gnu/bootloader/grub.scm +++ b/gnu/bootloader/grub.scm @@ -8,6 +8,7 @@ ;;; Copyright © 2020 Maxim Cournoyer ;;; Copyright © 2020 Stefan ;;; Copyright © 2022 Karl Hallsby +;;; Copyright © 2022 Denis 'GNUtoo' Carikli ;;; ;;; This file is part of GNU Guix. ;;; @@ -57,6 +58,7 @@ grub-bootloader grub-efi-bootloader grub-efi-removable-bootloader + grub-efi32-bootloader grub-efi-netboot-bootloader grub-mkrescue-bootloader grub-minimal-bootloader @@ -636,6 +638,29 @@ fi~%")))) "--bootloader-id=Guix" "--efi-directory" target-esp))))) +(define install-grub-efi32 + #~(lambda (bootloader efi-dir mount-point) + ;; There is nothing useful to do when called in the context of a disk + ;; image generation. + (when efi-dir + ;; Install GRUB onto the EFI partition mounted at EFI-DIR, for the + ;; system whose root is mounted at MOUNT-POINT. + (let ((grub-install (string-append bootloader "/sbin/grub-install")) + (install-dir (string-append mount-point "/boot")) + ;; When installing Guix, it's common to mount EFI-DIR below + ;; MOUNT-POINT rather than /boot/efi on the live image. + (target-esp (if (file-exists? (string-append mount-point efi-dir)) + (string-append mount-point efi-dir) + efi-dir))) + ;; Tell 'grub-install' that there might be a LUKS-encrypted /boot or + ;; root partition. + (setenv "GRUB_ENABLE_CRYPTODISK" "y") + (invoke/quiet grub-install "--boot-directory" install-dir + "--bootloader-id=Guix" + (cond ((target-x86?) "--target=i386-efi") + ((target-arm?) "--target=arm-efi")) + "--efi-directory" target-esp))))) + (define (install-grub-efi-netboot subdir) "Define a grub-efi-netboot bootloader installer for installation in SUBDIR, which is usually efi/Guix or efi/boot." @@ -768,6 +793,13 @@ considered for security aspects." (name 'grub-efi-removable-bootloader) (installer install-grub-efi-removable))) +(define grub-efi32-bootloader + (bootloader + (inherit grub-efi-bootloader) + (installer install-grub-efi32) + (name 'grub-efi32) + (package grub-efi32))) + (define grub-efi-netboot-bootloader (bootloader (inherit grub-efi-bootloader) diff --git a/gnu/build/bootloader.scm b/gnu/build/bootloader.scm index 9a89fe55cb..af6063a884 100644 --- a/gnu/build/bootloader.scm +++ b/gnu/build/bootloader.scm @@ -1,6 +1,8 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2017 Mathieu Othacehe ;;; Copyright © 2019 Ludovic Courtès +;;; Copyright © 2022 Denis 'GNUtoo' Carikli +;;; Copyright © 2022 Timothy Sample ;;; ;;; This file is part of GNU Guix. ;;; @@ -54,8 +56,12 @@ ;;; EFI bootloader. ;;; -(define (install-efi grub grub-config esp) - "Write a self-contained GRUB EFI loader to the mounted ESP using GRUB-CONFIG." +(define* (install-efi grub grub-config esp #:key targets) + "Write a self-contained GRUB EFI loader to the mounted ESP using +GRUB-CONFIG. + +If TARGETS is set, use its car as the GRUB image format and its cdr as +the output filename. Otherwise, use defaults for the host platform." (let* ((system %host-type) ;; Hard code the output location to a well-known path recognized by ;; compliant firmware. See "3.5.1.1 Removable Media Boot Behaviour": @@ -63,14 +69,15 @@ (grub-mkstandalone (string-append grub "/bin/grub-mkstandalone")) (efi-directory (string-append esp "/EFI/BOOT")) ;; Map grub target names to boot file names. - (efi-targets (cond ((string-prefix? "x86_64" system) - '("x86_64-efi" . "BOOTX64.EFI")) - ((string-prefix? "i686" system) - '("i386-efi" . "BOOTIA32.EFI")) - ((string-prefix? "armhf" system) - '("arm-efi" . "BOOTARM.EFI")) - ((string-prefix? "aarch64" system) - '("arm64-efi" . "BOOTAA64.EFI"))))) + (efi-targets (or targets + (cond ((string-prefix? "x86_64" system) + '("x86_64-efi" . "BOOTX64.EFI")) + ((string-prefix? "i686" system) + '("i386-efi" . "BOOTIA32.EFI")) + ((string-prefix? "armhf" system) + '("arm-efi" . "BOOTARM.EFI")) + ((string-prefix? "aarch64" system) + '("arm64-efi" . "BOOTAA64.EFI")))))) ;; grub-mkstandalone requires a TMPDIR to prepare the firmware image. (setenv "TMPDIR" esp) @@ -81,9 +88,12 @@ ;; Graft the configuration file onto the image. (string-append "boot/grub/grub.cfg=" grub-config)))) -(define (install-efi-loader grub-efi esp) +(define* (install-efi-loader grub-efi esp #:key targets) "Install in ESP directory the given GRUB-EFI bootloader. Configure it to -load the Grub bootloader located in the 'Guix_image' root partition." +load the Grub bootloader located in the 'Guix_image' root partition. + +If TARGETS is set, use its car as the GRUB image format and its cdr as +the output filename. Otherwise, use defaults for the host platform." (let ((grub-config "grub.cfg")) (call-with-output-file grub-config (lambda (port) @@ -97,5 +107,6 @@ load the Grub bootloader located in the 'Guix_image' root partition." insmod part_gpt~@ search --set=root --label Guix_image~@ configfile /boot/grub/grub.cfg~%"))) - (install-efi grub-efi grub-config esp) + (install-efi grub-efi grub-config esp #:targets targets) (delete-file grub-config))) + diff --git a/gnu/build/image.scm b/gnu/build/image.scm index ddfd34c111..321be8e4b1 100644 --- a/gnu/build/image.scm +++ b/gnu/build/image.scm @@ -6,6 +6,7 @@ ;;; Copyright © 2020, 2022 Tobias Geerinckx-Rice ;;; Copyright © 2020 Mathieu Othacehe ;;; Copyright © 2022 Pavel Shlyak +;;; Copyright © 2022 Denis 'GNUtoo' Carikli ;;; ;;; This file is part of GNU Guix. ;;; @@ -27,6 +28,7 @@ #:use-module (guix build syscalls) #:use-module (guix build utils) #:use-module (guix store database) + #:use-module (guix utils) #:use-module (gnu build bootloader) #:use-module (gnu build install) #:use-module (gnu build linux-boot) @@ -41,6 +43,7 @@ convert-disk-image genimage initialize-efi-partition + initialize-efi32-partition initialize-root-partition make-iso9660-image)) @@ -169,6 +172,17 @@ produced by #:references-graphs. Pass WAL-MODE? to call-with-database." "Install in ROOT directory, an EFI loader using GRUB-EFI." (install-efi-loader grub-efi root)) +(define* (initialize-efi32-partition root + #:key + grub-efi32 + #:allow-other-keys) + "Install in ROOT directory, an EFI 32bit loader using GRUB-EFI32." + (install-efi-loader grub-efi32 root + #:targets (cond ((target-x86?) + '("i386-efi" . "BOOTIA32.EFI")) + ((target-arm?) + '("arm-efi" . "BOOTARM.EFI"))))) + (define* (initialize-root-partition root #:key bootcfg diff --git a/gnu/packages/bootloaders.scm b/gnu/packages/bootloaders.scm index 91d259475a..71a10f54d5 100644 --- a/gnu/packages/bootloaders.scm +++ b/gnu/packages/bootloaders.scm @@ -15,6 +15,7 @@ ;;; Copyright © 2020, 2021 Pierre Langlois ;;; Copyright © 2021 Vincent Legoll ;;; Copyright © 2021 Brice Waegeneire +;;; Copyright © 2022 Denis 'GNUtoo' Carikli ;;; ;;; This file is part of GNU Guix. ;;; @@ -332,6 +333,18 @@ menu to select one of the installed operating systems.") "/bin/mcopy\""))) #t)))))))))) +(define-public grub-efi32 + (package + (inherit grub-efi) + (name "grub-efi32") + (synopsis "GRand Unified Boot loader (UEFI 32bit version)") + (arguments + `(,@(substitute-keyword-arguments (package-arguments grub-efi) + ((#:configure-flags flags + ''()) `(cons* ,(cond ((target-x86?) "--target=i386") + ((target-arm?) "--target=arm")) + ,flags))))))) + ;; Because grub searches hardcoded paths it's easiest to just build grub ;; again to make it find both grub-pc and grub-efi. There is a command ;; line argument which allows you to specify ONE platform - but diff --git a/gnu/system/image.scm b/gnu/system/image.scm index f02f6e0b8c..5972a944d7 100644 --- a/gnu/system/image.scm +++ b/gnu/system/image.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2020, 2021 Mathieu Othacehe ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen ;;; Copyright © 2022 Pavel Shlyak +;;; Copyright © 2022 Denis 'GNUtoo' Carikli ;;; ;;; This file is part of GNU Guix. ;;; @@ -66,6 +67,7 @@ root-label esp-partition + esp32-partition root-partition efi-disk-image @@ -75,6 +77,7 @@ image-with-os efi-raw-image-type + efi32-raw-image-type qcow2-image-type iso-image-type uncompressed-iso-image-type @@ -110,6 +113,11 @@ (flags '(esp)) (initializer (gexp initialize-efi-partition)))) +(define esp32-partition + (partition + (inherit esp-partition) + (initializer (gexp initialize-efi32-partition)))) + (define root-partition (partition (size 'guess) @@ -123,6 +131,11 @@ (format 'disk-image) (partitions (list esp-partition root-partition)))) +(define efi32-disk-image + (image + (format 'disk-image) + (partitions (list esp32-partition root-partition)))) + (define iso9660-image (image (format 'iso9660) @@ -164,6 +177,11 @@ set to the given OS." (name 'efi-raw) (constructor (cut image-with-os efi-disk-image <>)))) +(define efi32-raw-image-type + (image-type + (name 'efi32-raw) + (constructor (cut image-with-os efi32-disk-image <>)))) + (define qcow2-image-type (image-type (name 'qcow2) @@ -376,6 +394,7 @@ used in the image." #$(image-shared-store? image)) #:system-directory #$os #:grub-efi #+grub-efi + #:grub-efi32 #+grub-efi32 #:bootloader-package #+(bootloader-package bootloader) #:bootloader-installer