Subject: [PATCH v6 00/12] Rewrite bootloader subsystem.

From: Herman Rimm <[email-masked]>
Date: Tue, 24 Sep 2024 20:29:07 +0200

Hi all,

If you did not already know, some of the patch series contents was moved
to issue #73202 as separate commits, and patches relating to UKI will be
posted in #68524.

This patch series is based on v2 of issue #70131 (as well as #73202), so
I could test the rewritten U-Boot bootloader on a Nano Pi R4S.  It
works... unless you use guix deploy, in which case extlinux.conf is not
installed to /boot/extlinux, but /extlinux/boot!

Sergey fixed a GRUB bootloader paren.  I did so for U-Boot, and fixed
extlinux.conf installation (a bit).  Lilah updated the
bootloader-configuration-targets sanitizer to detect for 'part type
targets.  I made it more strict so nvme0n1, mmcblk0, etc. are still
'disk.  I rephrased some comments and documentation, used capital
letters and punctuation, and two spaces after periods.  I aligned the
arguments of procedures, mostly 'if' and 'and', only indenting by two
columns for 'begin', 'let' or 'with-*' procedures.  I used 'match' and
'match-lambda' instead of 'car', 'cddr', etc..  I added
core.cfg->core.img and make-grub.cfg to reduce indentation.

It's easier to see significant changes with 'git diff -w --color-moved'.

But I'm thinking of using define-configuration, to replace make-grub.cfg
with serialize-configuration, and to generate documentation with type
annotations.  In edge cases grub.cfg could then be overriden, so the
bootloader-configuration record is only left with fields which are
useful for multiple bootloaders and most common configurations, e.g.:

  (bootloader
    (bootloader-configuration
      (inherit %base-grub-configuration)
      (override (lambda (config)
                  ;; Record made with define-configuration.
                  (grub-configuration
                    (inherit config)
                    (keyboard-layout keyboard-layout)
                    (extra-initrd "~/just-for-grub.cfg.cpio.gz"))))))

  ;; Defaults per bootloader instead of singular record field defaults.
  (define %base-grub-configuration
    (bootloader-configuration
      (bootloader grub-efi-bootloader)
      (targets (list "/boot/efi"))
      ;; Same for each bootloader: should be a record field default.
      (override identity)))

I also want to make some record fields mutually exclusive, instead of
documenting which fields are required, or take priority, etc..  This
also applies to #73202.  For example:

(define-record-type* <bootloader-target>
  bootloader-target make-bootloader-target bootloader-target?
  (type bootloader-target-type)                            ; symbol
  (expected? bootloader-target-expected? (default #f))     ; bool
-  (path bootloader-target-path (default #f))               ; string|#f
-  (offset bootloader-target-offset (thunked)               ; symbol|#f
-          (default (and (bootloader-target-path this-record)
-                        (not (eq? (bootloader-target-type this-record) 'root))
-                        'root)))
-  (device bootloader-target-device (default #f))           ; string|#f
-  (file-system bootloader-target-file-system (default #f)) ; string|#f
-  (label bootloader-target-label (default #f))             ; string|#f
-  (uuid bootloader-target-uuid (default #f)))              ; uuid|#f
+  ;; Device is either a path-device, uuid, or string label.
+  (device bootloader-target-device)
+  (file-system bootloader-target-file-system (default #f))); string|#f
+
+(define-record-type* <path-device>
+  path-device make-path-device path-device?
+  (path path-device-path)                                  ; string
+  (offset path-device-offset (thunked) (default 'root)))   ; symbol|#f

Of course I will do more formatting, making use of the flat-map
procedure added in #73202.

The 'ESP full' warning should be limited to one in total, instead of for
each missing entry.  It could also refer to 'guix system
delete-generations'.

By the way, my Nano Pi R4S has the root partition on an HDD and the boot
partition on a microSD.  Whenever I reconfigure with a new kernel and
initrd, I need to copy them to /boot/gnu/store/, or U-boot will fall
back to an older generation.  Would it be a good idea to make Guix copy
these during installation, if it detects that the root and boot
partition are not on the same device?

Finally, changing the install procedure like so:

-  (let ((os-dir   (derivation->output-path os-drv))
-        (format   (lift format %store-monad))
-        (populate (lift2 populate-root-file-system %store-monad))
-        (profile  (string-append target "/var/guix/profiles/system")))
-    (mbegin %store-monad
+  (let* ((os-dir   (derivation->output-path os-drv))
+         (format   (lift format %store-monad))
+         (populate (lift2 populate-root-file-system %store-monad))
+         (profile  (string-append target "/var/guix/profiles/system"))
+         (alt (generation->boot-alternative profile 1)))
+    (mlet %store-monad
+        ((inst (apply install-bootloader local-eval bootloaders
+                      (list alt) #:dry-run? (not install-bootloader?)
+                      #:root-offset target bootmeta)))
       ;; Create a bunch of system files.
       (format log-port "populating '~a'...~%" target)
       (populate os-dir target)
       ;; Copy the bootloader's closure, which includes OS-DIR,
       ;; eventual background image and so on.
-      (mlet* %store-monad
-          ((alt -> (generation->boot-alternative profile 1))
-           (inst (apply install-bootloader local-eval bootloaders
-                        (list alt) #:dry-run? (not install-bootloader?)
-                        #:root-offset target bootmeta)))
-        (maybe-copy (derivation->output-path inst)))
+      (maybe-copy (derivation->output-path inst))

... makes %test-installed-os fail sooner, before the CPAN build error.
I don't know why.  I left it out of the patch series, though reconfigure
works.

Cheers,
Herman

Herman Rimm (1):
  gnu: system: image: Reduce subprocedure indentation.

Lilah Tascheter (11):
  gnu: bootloader: Remove obsolete bootloader fields.
  gnu: bootloader: grub: Rewrite entirely.
  gnu: bootloader: Update bootloader-configuration targets field.
  gnu: Core bootloader changes.
  gnu: bootloader: depthcharge: Rewrite completely.
  gnu: bootloader: extlinux: Rewrite completely.
  gnu: bootloader: u-boot: Rewrite completely.
  gnu: bootloader: Add Raspberry Pi bootloader.
  gnu: tests: Update tests to new targets system.
  gnu: system: Update examples.
  doc: Update bootloader documentation.

 doc/guix.texi                                 |  415 ++---
 gnu/bootloader.scm                            |  200 +--
 gnu/bootloader/depthcharge.scm                |  154 +-
 gnu/bootloader/extlinux.scm                   |  153 +-
 gnu/bootloader/grub.scm                       | 1332 +++++++----------
 gnu/bootloader/u-boot.scm                     |  536 +++----
 gnu/build/image.scm                           |   18 +-
 gnu/build/install.scm                         |   16 +-
 gnu/installer/parted.scm                      |   12 +-
 gnu/machine/ssh.scm                           |   66 +-
 gnu/packages/bootloaders.scm                  |  180 +--
 gnu/packages/raspberry-pi.scm                 |   18 -
 gnu/services/virtualization.scm               |   11 +-
 gnu/system.scm                                |   42 +-
 gnu/system/boot.scm                           |    3 +-
 gnu/system/examples/asus-c201.tmpl            |    6 +-
 gnu/system/examples/bare-bones.tmpl           |    7 +-
 gnu/system/examples/bare-hurd.tmpl            |    4 +-
 gnu/system/examples/beaglebone-black.tmpl     |    4 +-
 gnu/system/examples/desktop.tmpl              |    4 +-
 gnu/system/examples/docker-image.tmpl         |    6 +-
 gnu/system/examples/lightweight-desktop.tmpl  |    4 +-
 gnu/system/examples/plasma.tmpl               |    4 +-
 .../examples/raspberry-pi-64-nfs-root.tmpl    |   23 +-
 gnu/system/examples/raspberry-pi-64.tmpl      |   18 +-
 gnu/system/examples/vm-image.tmpl             |    5 +-
 gnu/system/hurd.scm                           |    4 +-
 gnu/system/image.scm                          |  237 +--
 gnu/system/images/hurd.scm                    |    4 +-
 gnu/system/images/novena.scm                  |    3 +-
 .../images/orangepi-r1-plus-lts-rk3328.scm    |    3 +-
 gnu/system/images/pine64.scm                  |    3 +-
 gnu/system/images/pinebook-pro.scm            |    3 +-
 gnu/system/images/rock64.scm                  |    3 +-
 gnu/system/images/unmatched.scm               |    3 +-
 gnu/system/images/visionfive2.scm             |    3 +-
 gnu/system/images/wsl2.scm                    |   14 +-
 gnu/system/install.scm                        |  101 +-
 gnu/system/vm.scm                             |   11 -
 gnu/tests.scm                                 |    4 +-
 gnu/tests/ganeti.scm                          |    4 +-
 gnu/tests/image.scm                           |    4 +-
 gnu/tests/install.scm                         |   80 +-
 gnu/tests/nfs.scm                             |    4 +-
 gnu/tests/telephony.scm                       |    4 +-
 gnu/tests/vnc.scm                             |    4 +-
 guix/scripts/system.scm                       |   93 +-
 guix/scripts/system/reconfigure.scm           |  158 +-
 tests/boot-parameters.scm                     |    2 +-
 49 files changed, 1680 insertions(+), 2310 deletions(-)

base-commit: 7ece5b8cf9f7b09fc67e40efd7a7f551bbbde5d7
-- 
2.45.2