[PATCH] WIP: gnu: bootloader: Add efi-stub-bootloader.

  • Open
  • quality assurance status badge
Details
One participant
  • Herman Rimm
Owner
unassigned
Submitted by
Herman Rimm
Severity
normal
H
H
Herman Rimm wrote on 24 Jan 22:58 +0100
(address . guix-patches@gnu.org)(name . Herman Rimm)(address . herman@rimm.ee)
941a6206de12ad011f9f2eda48a9a2d57c2c0734.1706133511.git.herman@rimm.ee
* doc/guix.texi (Bootloader Configuration)[bootloader,targets]: Document
efi-stub-bootloader.
* gnu/bootloader/efi-stub.scm: New file.
* gnu/local.mk: Register file.

Change-Id: Ia0ee0b8ded636f2647d9f4afaf8fed153e732b52
---
Hi all,
This patch adds efi-stub-bootloader which is based on uefi-uki-
bootloader from [bug#68524], that should get merged first.

Though maybe you can answer some of my questions:

1. How can I load (a newer) bootloader module? The --load-path option
is only meant to load package modules.

2. How do I get rid of:

(define (menu-entry->args e)
#~(string-join (list #$@(menu-entry-linux-arguments e))))

3. Related, what can I do about:

(list #$@(map-in-order menu-entry-label entries))
(list #$@(map-in-order menu-entry-linux entries))
(list #$@(map-in-order menu-entry->args entries))
(list #$@(map-in-order menu-entry-initrd entries))
(list #$@(map-in-order menu-entry-device entries))

4. If mount-point/boot/efi does not exist, the bootloader is installed
to /boot/efi. This is in case the user is installing guix to mount-point
but has the ESP mounted to /boot/efi. However the manual instructs the
user to mount it to /mnt/boot/efi before running 'guix system init'.
Also, if the user forgets to create (and mount) /mnt/boot/efi, the init
fails with a 'failed to get canonical path of /boot/efi' error. Is it
also okay to immediately fail if /mnt/boot/efi does not exist? Related
conditional statement:

(invoke install (if (file-exists? target-esp)
target-esp
efi-dir))

Thank you for your time,
Herman Rimm

doc/guix.texi | 35 ++++++++----
gnu/bootloader/efi-stub.scm | 110 ++++++++++++++++++++++++++++++++++++
gnu/local.mk | 1 +
3 files changed, 134 insertions(+), 12 deletions(-)
create mode 100644 gnu/bootloader/efi-stub.scm

Toggle diff (203 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 2cd05634bd..d7d158b7db 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -124,6 +124,8 @@
Copyright @copyright{} 2023 Saku Laesvuori@*
Copyright @copyright{} 2023 Graham James Addis@*
Copyright @copyright{} 2023 Tomas Volf@*
+Copyright @copyright{} 2024 Lilah Tascheter@*
+Copyright @copyright{} 2024 Herman Rimm@*
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -41110,9 +41112,10 @@ Bootloader Configuration
The bootloader to use, as a @code{bootloader} object. For now
@code{grub-bootloader}, @code{grub-efi-bootloader},
@code{grub-efi-removable-bootloader}, @code{grub-efi-netboot-bootloader},
-@code{grub-efi-netboot-removable-bootloader}, @code{extlinux-bootloader},
-@code{u-boot-bootloader}, @code{uefi-uki-bootloader}, and
-@code{uefi-uki-signed-bootloader} are supported.
+@code{grub-efi-netboot-removable-bootloader}, @code{efi-stub-bootloader},
+@code{extlinux-bootloader}, @code{u-boot-bootloader},
+@code{uefi-uki-bootloader} and @code{uefi-uki-signed-bootloader} are
+supported.
@cindex ARM, bootloaders
@cindex AArch64, bootloaders
@@ -41219,11 +41222,18 @@ Bootloader Configuration
unbootable.
@end quotation
+@vindex efi-stub-bootloader
+@code{efi-stub-bootloader} boots a linux kernel directly through UEFI, without
+a bootloader like GRUB. A practical advantage of this is allowing root/store
+encryption without an extra GRUB password entry and slow decryption step. It
+also makes it possible to have filesystems not yet supported by GRUB as root,
+like bcachefs.
+
@vindex uefi-uki-bootloader
-@code{uefi-uki-bootloader} boots a linux kernel directly through UEFI, without
-an intermediary like GRUB. The main practical advantage of this is allowing
-root/store encryption without an extra GRUB password entry and slow decryption
-step.
+@code{uefi-uki-bootloader} is like @code{efi-stub-bootloader}, but it boots a
+unified kernel image (UKI) instead. The main advantage is that the UKI can be
+booted from an EFI shell or file browser in the BIOS, when the corresponding
+UEFI boot entry is lost or removed.
@vindex uefi-uki-signed-bootloader
@code{uefi-uki-signed-bootloader} is like @code{uefi-uki-bootloader}, except
@@ -41246,11 +41256,12 @@ Bootloader Configuration
understood by the bootloader @command{installer} command, such as
@code{/dev/sda} or @code{(hd0)} (@pxref{Invoking grub-install,,, grub,
GNU GRUB Manual}). For @code{grub-efi-bootloader},
-@code{grub-efi-removable-bootloader}, @code{uefi-uki-bootloader}, and
-@code{uefi-uki-signed-bootloader}, they should be mount points of the EFI file
-system, usually @file{/boot/efi}. For @code{grub-efi-netboot-bootloader},
-@code{targets} should be the mount points corresponding to TFTP root directories
-served by your TFTP server.
+@code{grub-efi-removable-bootloader}, @code{efi-stub-bootloader},
+@code{uefi-uki-bootloader} and @code{uefi-uki-signed-bootloader},
+they should be mount points of the EFI file system, usually
+@file{/boot/efi}. For @code{grub-efi-netboot-bootloader},
+@code{targets} should be the mount points corresponding to TFTP root
+directories served by your TFTP server.
@item @code{menu-entries} (default: @code{'()})
A possibly empty list of @code{menu-entry} objects (see below), denoting
diff --git a/gnu/bootloader/efi-stub.scm b/gnu/bootloader/efi-stub.scm
new file mode 100644
index 0000000000..ed36cbef83
--- /dev/null
+++ b/gnu/bootloader/efi-stub.scm
@@ -0,0 +1,110 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2024 Marius Bakke <marius@gnu.org>
+;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space>
+;;; Copyright © 2024 Herman Rimm <herman@rimm.ee>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix 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 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix 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 GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu bootloader efi-stub)
+ #:use-module (gnu bootloader)
+ #:use-module (gnu packages bootloaders)
+ #:use-module (gnu packages linux)
+ #:use-module (guix gexp)
+ #:use-module (guix modules)
+ #:export (efi-stub-bootloader))
+
+;; Config generator makes script creating uki images;
+;; install runs script;
+;; install device is path to uefi dir.
+
+(define* (efi-stub-configuration-file config entries
+ #:key
+ (old-entries '())
+ #:allow-other-keys)
+ (define (menu-entry->args e)
+ #~(string-join (list #$@(menu-entry-linux-arguments e))))
+
+ (program-file "install-efi-stub"
+ (with-imported-modules (source-module-closure '((guix build utils)))
+ #~(let* ((target-esp (cadr (command-line)))
+ (vendir (string-append target-esp "/EFI/Guix"))
+ (schema (string-append vendir "/boot.mgr"))
+ (findmnt #$(file-append util-linux "/bin/findmnt"))
+ (efibootmgr #$(file-append efibootmgr "/sbin/efibootmgr")))
+ (use-modules (guix build utils) (ice-9 popen) (ice-9 textual-ports))
+
+ (define disk
+ (call-with-port
+ ;; TODO: try findmnt with multi-device Bcachefs and Btrfs.
+ (open-pipe* OPEN_READ findmnt "-fnro" "SOURCE" "-T" target-esp)
+ (lambda (port) (get-line port)))) ; only 1 line: the device
+
+ (when (file-exists? schema)
+ (call-with-input-file schema
+ (lambda (port)
+ (for-each (lambda (l)
+ (unless (string-null? l)
+ (system* efibootmgr "-q" "-B" "-L" l)))
+ (string-split (get-string-all port) #\lf)))))
+ (when (directory-exists? vendir) (delete-file-recursively vendir))
+
+ (define (out file)
+ (string-append vendir "/" (basename file)))
+
+ (define (boot file)
+ (string-append "\\EFI\\Guix\\" (basename file)))
+
+ (mkdir-p vendir)
+ (call-with-output-file schema
+ (lambda (port)
+ (for-each
+ (lambda (label loader args initrd device)
+ (copy-file loader (out loader))
+ (copy-file initrd (out initrd))
+ (invoke efibootmgr
+ "-q" "-c" "-L" label "-d" disk "-l" (boot loader)
+ "-u" (string-append args " initrd=" (boot initrd)))
+ (put-string port label)
+ (put-char port #\lf))
+ (list #$@(map-in-order menu-entry-label entries))
+ (list #$@(map-in-order menu-entry-linux entries))
+ (list #$@(map-in-order menu-entry->args entries))
+ (list #$@(map-in-order menu-entry-initrd entries))
+ (list #$@(map-in-order menu-entry-device entries)))))))))
+
+(define install-efi-stub
+ ;; mount-point is /mnt in guix system init /etc/config.scm /mnt/point;
+ ;; efi-dir comes from target list of bootloader configuration.
+ #~(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
+ (let ((install (string-append mount-point "/boot/install-efi-stub.scm"))
+ ;; When installing Guix, it's common to mount EFI-DIR below
+ ;; MOUNT-POINT rather than /boot/efi on the live image.
+ (target-esp (string-append mount-point efi-dir)))
+ (invoke install (if (file-exists? target-esp)
+ target-esp
+ efi-dir))))))
+
+(define efi-stub-bootloader
+ (bootloader
+ (name 'efi-stub)
+ (package #f) ; The EFI boot stub is a part of linux.
+ (installer install-efi-stub)
+ (disk-image-installer #f)
+ (configuration-file "/boot/install-efi-stub.scm")
+ (configuration-file-generator efi-stub-configuration-file)))
diff --git a/gnu/local.mk b/gnu/local.mk
index 43d02ee793..1b75fa7487 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -87,6 +87,7 @@ GNU_SYSTEM_MODULES = \
%D%/artwork.scm \
%D%/bootloader.scm \
%D%/bootloader/grub.scm \
+ %D%/bootloader/efi-stub.scm \
%D%/bootloader/extlinux.scm \
%D%/bootloader/u-boot.scm \
%D%/bootloader/depthcharge.scm \

base-commit: da3e6aea0a750246e8a9120d62441c3df65faff0
prerequisite-patch-id: d5fe3fcbdd7961f687f72d0e4262af7fffe92435
prerequisite-patch-id: 9eddb6700a8d8fe0f5604d084ca90cd23381613b
prerequisite-patch-id: 38851b9a3c7437328ceccff94815abd939e6d1e5
--
2.41.0
?
Your comment

Commenting via the web interface is currently disabled.

To comment on this conversation send an email to 68702@debbugs.gnu.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 68702
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch