GNU bug report logs - #68702
[PATCH] WIP: gnu: bootloader: Add efi-stub-bootloader.

Previous Next

Package: guix-patches;

Reported by: Herman Rimm <herman <at> rimm.ee>

Date: Wed, 24 Jan 2024 22:06:01 UTC

Severity: normal

Tags: patch

To reply to this bug, email your comments to 68702 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#68702; Package guix-patches. (Wed, 24 Jan 2024 22:06:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Herman Rimm <herman <at> rimm.ee>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Wed, 24 Jan 2024 22:06:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Herman Rimm <herman <at> rimm.ee>
To: guix-patches <at> gnu.org
Cc: Herman Rimm <herman <at> rimm.ee>
Subject: [PATCH] WIP: gnu: bootloader: Add efi-stub-bootloader.
Date: Wed, 24 Jan 2024 22:58:31 +0100
* 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

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 <at> gnu.org>
+;;; Copyright © 2024 Lilah Tascheter <lilah <at> lunabee.space>
+;;; Copyright © 2024 Herman Rimm <herman <at> 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





This bug report was last modified 100 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.