mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-24 21:38:07 -05:00
gnu: bootloader: Rework chaining, add grub-efi-netboot-removable-bootloader.
This rework allows to use an (efi-bootloader-chain) like this, which is able to boot over network or local storage, depending on whether the bootloader target has support for symbolic links: (operating-system (bootloader (bootloader-configuration (bootloader (efi-bootloader-chain grub-efi-netboot-removable-bootloader #:packages (list my-firmware-package my-u-boot-package) #:files (list (plain-file "config.txt" "kernel=u-boot.bin")) #:hooks my-special-bootloader-profile-manipulator)) (targets '("/booti/efi")) …)) …) * doc/guix.texi (Bootloader Configuration): Describe the new ‘grub-efi-netboot-removable-bootloader’. Mention the file names used and that the UEFI Boot Manager is not modified. Advise to disable write-access over TFTP. * gnu/bootloader.scm (efi-bootloader-profile): Allow a list of packages and collect everything directly in the profile, avoiding a separate collection directory. Renamed the profile from "bootloader-profile" to "efi-bootloader-profile". [bootloader-collection]: Rename to... [efi-bootloader-profile-hook]: ... this and remove unused modules. Do not create the now extraneous collection directory. (efi-bootloader-chain): Add PACKAGES and DISK-IMAGE-INSTALLER arguments. Remove handling of the collection directory, now only calling the given installer procedure. * gnu/bootloader/grub.scm (make-grub-efi-netboot-installer): New helper. (make-grub-configuration): New helper based on (grub-configuration-file). Add a GRUB argument, fix indentation, remove previous code retrieving GRUB from CONFIG. (grub-configuration-file): Make use of make-grub-configuration. (grub-efi-configuration-file): New procedure. (grub-cfg): New variable to replace "/boot/grub/grub.cfg". (install-grub-efi-netboot): Remove, splitting logic to... (make-grub-efi-netboot-installer): ... this new helper procedure, as well as to make-grub-efi-netboot, added below. (grub-bootloader): Adjust to use the GRUB-CFG. (grub-efi-bootloader): Likewise. Removed inheritance and declare all fields explicitly. (make-grub-efi-netboot-bootloader): New procedure. (grub-efi-netboot-bootloader): Use it. (grub-efi-netboot-removable-bootloader): New variable. * gnu/packages/bootloaders.scm (make-grub-efi-netboot): New procedure. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Modified-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
This commit is contained in:
parent
1a63aea943
commit
a9acbf919a
4 changed files with 323 additions and 151 deletions
|
@ -37997,8 +37997,9 @@ The type of a bootloader configuration declaration.
|
||||||
@cindex BIOS, bootloader
|
@cindex BIOS, bootloader
|
||||||
The bootloader to use, as a @code{bootloader} object. For now
|
The bootloader to use, as a @code{bootloader} object. For now
|
||||||
@code{grub-bootloader}, @code{grub-efi-bootloader},
|
@code{grub-bootloader}, @code{grub-efi-bootloader},
|
||||||
@code{grub-efi-netboot-bootloader}, @code{grub-efi-removable-bootloader},
|
@code{grub-efi-removable-bootloader}, @code{grub-efi-netboot-bootloader},
|
||||||
@code{extlinux-bootloader} and @code{u-boot-bootloader} are supported.
|
@code{grub-efi-netboot-removable-bootloader}, @code{extlinux-bootloader}
|
||||||
|
and @code{u-boot-bootloader} are supported.
|
||||||
|
|
||||||
@cindex ARM, bootloaders
|
@cindex ARM, bootloaders
|
||||||
@cindex AArch64, bootloaders
|
@cindex AArch64, bootloaders
|
||||||
|
@ -38007,15 +38008,29 @@ modules. In particular, @code{(gnu bootloader u-boot)} contains definitions
|
||||||
of bootloaders for a wide range of ARM and AArch64 systems, using the
|
of bootloaders for a wide range of ARM and AArch64 systems, using the
|
||||||
@uref{https://www.denx.de/wiki/U-Boot/, U-Boot bootloader}.
|
@uref{https://www.denx.de/wiki/U-Boot/, U-Boot bootloader}.
|
||||||
|
|
||||||
|
@vindex grub-bootloader
|
||||||
|
@code{grub-bootloader} allows you to boot in particular Intel-based machines
|
||||||
|
in ``legacy'' BIOS mode.
|
||||||
|
|
||||||
@vindex grub-efi-bootloader
|
@vindex grub-efi-bootloader
|
||||||
@code{grub-efi-bootloader} allows to boot on modern systems using the
|
@code{grub-efi-bootloader} allows to boot on modern systems using the
|
||||||
@dfn{Unified Extensible Firmware Interface} (UEFI). This is what you should
|
@dfn{Unified Extensible Firmware Interface} (UEFI). This is what you should
|
||||||
use if the installation image contains a @file{/sys/firmware/efi} directory
|
use if the installation image contains a @file{/sys/firmware/efi} directory
|
||||||
when you boot it on your system.
|
when you boot it on your system.
|
||||||
|
|
||||||
@vindex grub-bootloader
|
@vindex grub-efi-removable-bootloader
|
||||||
@code{grub-bootloader} allows you to boot in particular Intel-based machines
|
@code{grub-efi-removable-bootloader} allows you to boot your system from
|
||||||
in ``legacy'' BIOS mode.
|
removable media by writing the GRUB file to the UEFI-specification location of
|
||||||
|
@file{/EFI/BOOT/BOOTX64.efi} of the boot directory, usually @file{/boot/efi}.
|
||||||
|
This is also useful for some UEFI firmwares that ``forget'' their configuration
|
||||||
|
from their non-volatile storage. Like @code{grub-efi-bootloader}, this can only
|
||||||
|
be used if the @file{/sys/firmware/efi} directory is available.
|
||||||
|
|
||||||
|
@quotation Note
|
||||||
|
This @emph{will} overwrite the GRUB file from any other operating systems that
|
||||||
|
also place their GRUB file in the UEFI-specification location; making them
|
||||||
|
unbootable.
|
||||||
|
@end quotation
|
||||||
|
|
||||||
@vindex grub-efi-netboot-bootloader
|
@vindex grub-efi-netboot-bootloader
|
||||||
@code{grub-efi-netboot-bootloader} allows you to boot your system over network
|
@code{grub-efi-netboot-bootloader} allows you to boot your system over network
|
||||||
|
@ -38024,9 +38039,10 @@ build a diskless Guix system.
|
||||||
|
|
||||||
The installation of the @code{grub-efi-netboot-bootloader} generates the
|
The installation of the @code{grub-efi-netboot-bootloader} generates the
|
||||||
content of the TFTP root directory at @code{targets} (@pxref{Bootloader
|
content of the TFTP root directory at @code{targets} (@pxref{Bootloader
|
||||||
Configuration, @code{targets}}), to be served by a TFTP server. You may
|
Configuration, @code{targets}}) below the sub-directory @file{efi/Guix}, to be
|
||||||
want to mount your TFTP server directories onto the @code{targets} to
|
served by a TFTP server. You may want to mount your TFTP server directories
|
||||||
move the required files to the TFTP server automatically.
|
onto the @code{targets} to move the required files to the TFTP server
|
||||||
|
automatically during installation.
|
||||||
|
|
||||||
If you plan to use an NFS root file system as well (actually if you mount the
|
If you plan to use an NFS root file system as well (actually if you mount the
|
||||||
store from an NFS share), then the TFTP server needs to serve the file
|
store from an NFS share), then the TFTP server needs to serve the file
|
||||||
|
@ -38055,25 +38071,34 @@ this constellation the symlinks will work.
|
||||||
For other constellations you will have to program your own bootloader
|
For other constellations you will have to program your own bootloader
|
||||||
installer, which then takes care to make necessary files from the store
|
installer, which then takes care to make necessary files from the store
|
||||||
accessible through TFTP, for example by copying them into the TFTP root
|
accessible through TFTP, for example by copying them into the TFTP root
|
||||||
directory to your @code{targets}.
|
directory for your @code{targets}.
|
||||||
|
|
||||||
It is important to note that symlinks pointing outside the TFTP root directory
|
It is important to note that symlinks pointing outside the TFTP root directory
|
||||||
may need to be allowed in the configuration of your TFTP server. Further the
|
may need to be allowed in the configuration of your TFTP server. Further the
|
||||||
store link exposes the whole store through TFTP@. Both points need to be
|
store link exposes the whole store through TFTP@. Both points need to be
|
||||||
considered carefully for security aspects.
|
considered carefully for security aspects. It is advised to disable any TFTP
|
||||||
|
write access!
|
||||||
|
|
||||||
|
Please note, that this bootloader will not modify the ‘UEFI Boot Manager’ of
|
||||||
|
the system.
|
||||||
|
|
||||||
Beside the @code{grub-efi-netboot-bootloader}, the already mentioned TFTP and
|
Beside the @code{grub-efi-netboot-bootloader}, the already mentioned TFTP and
|
||||||
NFS servers, you also need a properly configured DHCP server to make the booting
|
NFS servers, you also need a properly configured DHCP server to make the booting
|
||||||
over netboot possible. For all this we can currently only recommend you to look
|
over netboot possible. For all this we can currently only recommend you to look
|
||||||
for instructions about @acronym{PXE, Preboot eXecution Environment}.
|
for instructions about @acronym{PXE, Preboot eXecution Environment}.
|
||||||
|
|
||||||
@vindex grub-efi-removable-bootloader
|
If a local EFI System Partition (ESP) or a similar partition with a FAT
|
||||||
@code{grub-efi-removable-bootloader} allows you to boot your system from
|
file system is mounted in @code{targets}, then symlinks cannot be
|
||||||
removable media by writing the GRUB file to the UEFI-specification location of
|
created. In this case everything will be prepared for booting from
|
||||||
@file{/EFI/BOOT/BOOTX64.efi} of the boot directory, usually @file{/boot/efi}.
|
local storage, matching the behavior of @code{grub-efi-bootloader}, with
|
||||||
This is also useful for some UEFI firmwares that ``forget'' their configuration
|
the difference that all GRUB binaries are copied to @code{targets},
|
||||||
from their non-volatile storage. Like @code{grub-efi-bootloader}, this can only
|
necessary for booting over the network.
|
||||||
be used if the @file{/sys/firmware/efi} directory is available.
|
|
||||||
|
@vindex grub-efi-netboot-removable-bootloader
|
||||||
|
@code{grub-efi-netboot-removable-bootloader} is identical to
|
||||||
|
@code{grub-efi-netboot-bootloader} with the exception that the
|
||||||
|
sub-directory @file{efi/boot} will be used instead of @file{efi/Guix} to
|
||||||
|
comply with the UEFI specification for removable media.
|
||||||
|
|
||||||
@quotation Note
|
@quotation Note
|
||||||
This @emph{will} overwrite the GRUB file from any other operating systems that
|
This @emph{will} overwrite the GRUB file from any other operating systems that
|
||||||
|
|
|
@ -322,26 +322,22 @@ (define (lookup-bootloader-by-name name)
|
||||||
(force %bootloaders))
|
(force %bootloaders))
|
||||||
(leave (G_ "~a: no such bootloader~%") name)))
|
(leave (G_ "~a: no such bootloader~%") name)))
|
||||||
|
|
||||||
(define (efi-bootloader-profile files bootloader-package hooks)
|
(define (efi-bootloader-profile packages files hooks)
|
||||||
"Creates a profile with BOOTLOADER-PACKAGE and a directory collection/ with
|
"Creates a profile from the lists of PACKAGES and FILES from the store.
|
||||||
links to additional FILES from the store. This collection is meant to be used
|
This profile is meant to be used by the bootloader-installer.
|
||||||
by the bootloader installer.
|
|
||||||
|
|
||||||
FILES is a list of file or directory names from the store, which will be
|
FILES is a list of file or directory names from the store, which will be
|
||||||
symlinked into the collection/ directory. If a directory name ends with '/',
|
symlinked into the profile. If a directory name ends with '/', then the
|
||||||
then the directory content instead of the directory itself will be symlinked
|
directory content instead of the directory itself will be symlinked into the
|
||||||
into the collection/ directory.
|
profile.
|
||||||
|
|
||||||
FILES may contain file like objects produced by functions like plain-file,
|
FILES may contain file like objects produced by procedures like plain-file,
|
||||||
local-file, etc., or package contents produced with file-append.
|
local-file, etc., or package contents produced with file-append.
|
||||||
|
|
||||||
HOOKS lists additional hook functions to modify the profile."
|
HOOKS lists additional hook functions to modify the profile."
|
||||||
(define (bootloader-collection manifest)
|
(define (efi-bootloader-profile-hook manifest)
|
||||||
(define build
|
(define build
|
||||||
(with-imported-modules '((guix build utils)
|
(with-imported-modules '((guix build utils))
|
||||||
(ice-9 ftw)
|
|
||||||
(srfi srfi-1)
|
|
||||||
(srfi srfi-26))
|
|
||||||
#~(begin
|
#~(begin
|
||||||
(use-modules ((guix build utils)
|
(use-modules ((guix build utils)
|
||||||
#:select (mkdir-p strip-store-file-name))
|
#:select (mkdir-p strip-store-file-name))
|
||||||
|
@ -365,8 +361,7 @@ (define name-ends-with-/? (cut string-suffix? "/" <>))
|
||||||
(define (name-is-store-entry? name)
|
(define (name-is-store-entry? name)
|
||||||
"Return #t if NAME is a direct store entry and nothing inside."
|
"Return #t if NAME is a direct store entry and nothing inside."
|
||||||
(not (string-index (strip-store-file-name name) #\/)))
|
(not (string-index (strip-store-file-name name) #\/)))
|
||||||
(let* ((collection (string-append #$output "/collection"))
|
(let* ((files '#$files)
|
||||||
(files '#$files)
|
|
||||||
(directories (filter name-ends-with-/? files))
|
(directories (filter name-ends-with-/? files))
|
||||||
(names-from-directories
|
(names-from-directories
|
||||||
(append-map (lambda (directory)
|
(append-map (lambda (directory)
|
||||||
|
@ -374,11 +369,11 @@ (define (name-is-store-entry? name)
|
||||||
directories))
|
directories))
|
||||||
(names (append names-from-directories
|
(names (append names-from-directories
|
||||||
(remove name-ends-with-/? files))))
|
(remove name-ends-with-/? files))))
|
||||||
(mkdir-p collection)
|
(mkdir-p #$output)
|
||||||
(if (every file-exists? names)
|
(if (every file-exists? names)
|
||||||
(begin
|
(begin
|
||||||
(for-each (lambda (name)
|
(for-each (lambda (name)
|
||||||
(symlink-to name collection
|
(symlink-to name #$output
|
||||||
(if (name-is-store-entry? name)
|
(if (name-is-store-entry? name)
|
||||||
strip-store-file-name
|
strip-store-file-name
|
||||||
basename)))
|
basename)))
|
||||||
|
@ -386,57 +381,63 @@ (define (name-is-store-entry? name)
|
||||||
#t)
|
#t)
|
||||||
#f)))))
|
#f)))))
|
||||||
|
|
||||||
(gexp->derivation "bootloader-collection"
|
(gexp->derivation "efi-bootloader-profile"
|
||||||
build
|
build
|
||||||
#:local-build? #t
|
#:local-build? #t
|
||||||
#:substitutable? #f
|
#:substitutable? #f
|
||||||
#:properties
|
#:properties
|
||||||
`((type . profile-hook)
|
`((type . profile-hook)
|
||||||
(hook . bootloader-collection))))
|
(hook . efi-bootloader-profile-hook))))
|
||||||
|
|
||||||
(profile (content (packages->manifest (list bootloader-package)))
|
(profile (content (packages->manifest packages))
|
||||||
(name "bootloader-profile")
|
(name "efi-bootloader-profile")
|
||||||
(hooks (append (list bootloader-collection) hooks))
|
(hooks (cons efi-bootloader-profile-hook hooks))
|
||||||
(locales? #f)
|
(locales? #f)
|
||||||
(allow-collisions? #f)
|
(allow-collisions? #f)
|
||||||
(relative-symlinks? #f)))
|
(relative-symlinks? #f)))
|
||||||
|
|
||||||
(define* (efi-bootloader-chain files
|
(define* (efi-bootloader-chain final-bootloader
|
||||||
final-bootloader
|
|
||||||
#:key
|
#:key
|
||||||
|
(packages '())
|
||||||
|
(files '())
|
||||||
(hooks '())
|
(hooks '())
|
||||||
installer)
|
installer
|
||||||
"Define a bootloader chain with FINAL-BOOTLOADER as the final bootloader and
|
disk-image-installer)
|
||||||
certain directories and files from the store given in the list of FILES.
|
"Define a chain of bootloaders with the FINAL-BOOTLOADER, optional PACKAGES,
|
||||||
|
and optional directories and files from the store given in the list of FILES.
|
||||||
|
|
||||||
FILES may contain file like objects produced by functions like plain-file,
|
The package of the FINAL-BOOTLOADER and all PACKAGES and FILES will be placed
|
||||||
local-file, etc., or package contents produced with file-append. They will be
|
in an efi-bootloader-profile, which will be passed to the INSTALLER.
|
||||||
collected inside a directory collection/ inside a generated bootloader profile,
|
|
||||||
which will be passed to the INSTALLER.
|
FILES may contain file-like objects produced by procedures like plain-file,
|
||||||
|
local-file, etc., or package contents produced with file-append.
|
||||||
|
|
||||||
If a directory name in FILES ends with '/', then the directory content instead
|
If a directory name in FILES ends with '/', then the directory content instead
|
||||||
of the directory itself will be symlinked into the collection/ directory.
|
of the directory itself will be symlinked into the efi-bootloader-profile.
|
||||||
|
|
||||||
The procedures in the HOOKS list can be used to further modify the bootloader
|
The procedures in the HOOKS list can be used to further modify the bootloader
|
||||||
profile. It is possible to pass a single function instead of a list.
|
profile. It is possible to pass a single function instead of a list.
|
||||||
|
|
||||||
If the INSTALLER argument is used, then this function will be called to install
|
If the INSTALLER argument is used, then this gexp procedure will be called to
|
||||||
the bootloader. Otherwise the installer of the FINAL-BOOTLOADER will be called."
|
install the efi-bootloader-profile. Otherwise the installer of the
|
||||||
(let* ((final-installer (or installer
|
FINAL-BOOTLOADER will be called.
|
||||||
(bootloader-installer final-bootloader)))
|
|
||||||
(profile (efi-bootloader-profile files
|
If the DISK-IMAGE-INSTALLER is used, then this gexp procedure will be called
|
||||||
(bootloader-package final-bootloader)
|
to install the efi-bootloader-profile into a disk image. Otherwise the
|
||||||
(if (list? hooks)
|
disk-image-installer of the FINAL-BOOTLOADER will be called."
|
||||||
hooks
|
(bootloader
|
||||||
(list hooks)))))
|
(inherit final-bootloader)
|
||||||
(bootloader
|
(name "efi-bootloader-chain")
|
||||||
(inherit final-bootloader)
|
(package
|
||||||
(package profile)
|
(efi-bootloader-profile (cons (bootloader-package final-bootloader)
|
||||||
(installer
|
packages)
|
||||||
#~(lambda (bootloader target mount-point)
|
files
|
||||||
(#$final-installer bootloader target mount-point)
|
(if (list? hooks)
|
||||||
(copy-recursively
|
hooks
|
||||||
(string-append bootloader "/collection")
|
(list hooks))))
|
||||||
(string-append mount-point target)
|
(installer
|
||||||
#:follow-symlinks? #t
|
(or installer
|
||||||
#:log (%make-void-port "w")))))))
|
(bootloader-installer final-bootloader)))
|
||||||
|
(disk-image-installer
|
||||||
|
(or disk-image-installer
|
||||||
|
(bootloader-disk-image-installer final-bootloader)))))
|
||||||
|
|
|
@ -53,13 +53,14 @@ (define-module (gnu bootloader grub)
|
||||||
grub-theme-gfxmode
|
grub-theme-gfxmode
|
||||||
|
|
||||||
install-grub-efi-removable
|
install-grub-efi-removable
|
||||||
install-grub-efi-netboot
|
make-grub-efi-netboot-installer
|
||||||
|
|
||||||
grub-bootloader
|
grub-bootloader
|
||||||
grub-efi-bootloader
|
grub-efi-bootloader
|
||||||
grub-efi-removable-bootloader
|
grub-efi-removable-bootloader
|
||||||
grub-efi32-bootloader
|
grub-efi32-bootloader
|
||||||
grub-efi-netboot-bootloader
|
grub-efi-netboot-bootloader
|
||||||
|
grub-efi-netboot-removable-bootloader
|
||||||
grub-mkrescue-bootloader
|
grub-mkrescue-bootloader
|
||||||
grub-minimal-bootloader
|
grub-minimal-bootloader
|
||||||
|
|
||||||
|
@ -353,7 +354,7 @@ (define (grub-root-search device file)
|
||||||
((or #f (? string?))
|
((or #f (? string?))
|
||||||
#~(format #f "search --file --set ~a" #$file)))))
|
#~(format #f "search --file --set ~a" #$file)))))
|
||||||
|
|
||||||
(define* (grub-configuration-file config entries
|
(define* (make-grub-configuration grub config entries
|
||||||
#:key
|
#:key
|
||||||
(locale #f)
|
(locale #f)
|
||||||
(system (%current-system))
|
(system (%current-system))
|
||||||
|
@ -453,9 +454,7 @@ (define (sugar)
|
||||||
(define locale-config
|
(define locale-config
|
||||||
(let* ((entry (first all-entries))
|
(let* ((entry (first all-entries))
|
||||||
(device (menu-entry-device entry))
|
(device (menu-entry-device entry))
|
||||||
(mount-point (menu-entry-device-mount-point entry))
|
(mount-point (menu-entry-device-mount-point entry)))
|
||||||
(bootloader (bootloader-configuration-bootloader config))
|
|
||||||
(grub (bootloader-package bootloader)))
|
|
||||||
#~(let ((locale #$(and locale
|
#~(let ((locale #$(and locale
|
||||||
(locale-definition-source
|
(locale-definition-source
|
||||||
(locale-name->definition locale))))
|
(locale-name->definition locale))))
|
||||||
|
@ -481,8 +480,6 @@ (define locale-config
|
||||||
|
|
||||||
(define keyboard-layout-config
|
(define keyboard-layout-config
|
||||||
(let* ((layout (bootloader-configuration-keyboard-layout config))
|
(let* ((layout (bootloader-configuration-keyboard-layout config))
|
||||||
(grub (bootloader-package
|
|
||||||
(bootloader-configuration-bootloader config)))
|
|
||||||
(keymap* (and layout
|
(keymap* (and layout
|
||||||
(keyboard-layout-file layout #:grub grub)))
|
(keyboard-layout-file layout #:grub grub)))
|
||||||
(entry (first all-entries))
|
(entry (first all-entries))
|
||||||
|
@ -533,6 +530,16 @@ (define builder
|
||||||
#:options '(#:local-build? #t
|
#:options '(#:local-build? #t
|
||||||
#:substitutable? #f)))
|
#:substitutable? #f)))
|
||||||
|
|
||||||
|
(define (grub-configuration-file config . args)
|
||||||
|
(let* ((bootloader (bootloader-configuration-bootloader config))
|
||||||
|
(grub (bootloader-package bootloader)))
|
||||||
|
(apply make-grub-configuration grub config args)))
|
||||||
|
|
||||||
|
(define (grub-efi-configuration-file . args)
|
||||||
|
(apply make-grub-configuration grub-efi args))
|
||||||
|
|
||||||
|
(define grub-cfg "/boot/grub/grub.cfg")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
@ -674,42 +681,31 @@ (define install-grub-efi32
|
||||||
((target-arm?) "--target=arm-efi"))
|
((target-arm?) "--target=arm-efi"))
|
||||||
"--efi-directory" target-esp)))))
|
"--efi-directory" target-esp)))))
|
||||||
|
|
||||||
(define (install-grub-efi-netboot subdir)
|
(define* (make-grub-efi-netboot-installer grub-efi grub-cfg subdir)
|
||||||
"Define a grub-efi-netboot bootloader installer for installation in SUBDIR,
|
"Make a bootloader-installer for a grub-efi-netboot bootloader, which expects
|
||||||
which is usually efi/Guix or efi/boot."
|
its files in SUBDIR and its configuration file in GRUB-CFG.
|
||||||
(let* ((system (string-split (nix-system->gnu-triplet
|
|
||||||
(or (%current-target-system)
|
As a grub-efi-netboot package is already pre-installed by 'grub-mknetdir', the
|
||||||
(%current-system)))
|
installer basically copies all files from the bootloader-package (or profile)
|
||||||
#\-))
|
into the bootloader-target directory.
|
||||||
(arch (first system))
|
|
||||||
(boot-efi-link (match system
|
Additionally for network booting over TFTP, two relative symlinks to the store
|
||||||
;; These are the supportend systems and the names
|
and to the GRUB-CFG file are necessary. Due to this a TFTP root directory must
|
||||||
;; defined by the UEFI standard for removable media.
|
not be located on a FAT file-system.
|
||||||
(("i686" _ ...) "/bootia32.efi")
|
|
||||||
(("x86_64" _ ...) "/bootx64.efi")
|
If the bootloader-target does not support symlinks, then it is assumed to be a
|
||||||
(("arm" _ ...) "/bootarm.efi")
|
kind of EFI System Partition (ESP). In this case an intermediate configuration
|
||||||
(("aarch64" _ ...) "/bootaa64.efi")
|
file is created with the help of GRUB-EFI to load the GRUB-CFG.
|
||||||
(("riscv" _ ...) "/bootriscv32.efi")
|
|
||||||
(("riscv64" _ ...) "/bootriscv64.efi")
|
The installer is usable for any efi-bootloader-chain, which prepares the
|
||||||
;; Other systems are not supported, although defined.
|
bootloader-profile in a way ready for copying.
|
||||||
;; (("riscv128" _ ...) "/bootriscv128.efi")
|
|
||||||
;; (("ia64" _ ...) "/bootia64.efi")
|
The installer does not manipulate the system's 'UEFI Boot Manager'.
|
||||||
((_ ...) #f)))
|
|
||||||
(core-efi (string-append
|
The returned installer accepts the BOOTLOADER, TARGET and MOUNT-POINT
|
||||||
;; This is the arch dependent file name of GRUB, e.g.
|
arguments. Its job is to copy the BOOTLOADER, which must be a pre-installed
|
||||||
;; i368-efi/core.efi or arm64-efi/core.efi.
|
grub-efi-netboot package with a SUBDIR like efi/boot or efi/Guix, below the
|
||||||
(match arch
|
directory TARGET for the system whose root is mounted at MOUNT-POINT.
|
||||||
("i686" "i386")
|
|
||||||
("aarch64" "arm64")
|
|
||||||
("riscv" "riscv32")
|
|
||||||
(_ arch))
|
|
||||||
"-efi/core.efi")))
|
|
||||||
(with-imported-modules
|
|
||||||
'((guix build union))
|
|
||||||
#~(lambda (bootloader target mount-point)
|
|
||||||
"Install the BOOTLOADER, which must be the package grub, as e.g.
|
|
||||||
bootx64.efi or bootaa64.efi into SUBDIR, which is usually efi/Guix or efi/boot,
|
|
||||||
below the directory TARGET for the system whose root is mounted at MOUNT-POINT.
|
|
||||||
|
|
||||||
MOUNT-POINT is the last argument in 'guix system init /etc/config.scm mnt/point'
|
MOUNT-POINT is the last argument in 'guix system init /etc/config.scm mnt/point'
|
||||||
or '/' for other 'guix system' commands.
|
or '/' for other 'guix system' commands.
|
||||||
|
@ -719,17 +715,19 @@ (define (install-grub-efi-netboot subdir)
|
||||||
|
|
||||||
(operating-system
|
(operating-system
|
||||||
(bootloader (bootloader-configuration
|
(bootloader (bootloader-configuration
|
||||||
(targets '(\"/boot\"))
|
(targets '(\"/boot/efi\"))
|
||||||
…))
|
…))
|
||||||
…)
|
…)
|
||||||
|
|
||||||
TARGET is required to be an absolute directory name, usually mounted via NFS,
|
TARGET is required to be an absolute directory name, usually mounted via NFS,
|
||||||
and finally needs to be provided by a TFTP server as the TFTP root directory.
|
and finally needs to be provided by a TFTP server as
|
||||||
|
the TFTP root directory.
|
||||||
|
|
||||||
|
Usually the installer will be used to prepare network booting over TFTP. Then
|
||||||
GRUB will load tftp://server/SUBDIR/grub.cfg and this file will instruct it to
|
GRUB will load tftp://server/SUBDIR/grub.cfg and this file will instruct it to
|
||||||
load more files from the store like tftp://server/gnu/store/…-linux…/Image.
|
load more files from the store like tftp://server/gnu/store/…-linux…/Image.
|
||||||
|
|
||||||
To make this possible two symlinks will be created. The first symlink points
|
To make this possible two symlinks are created. The first symlink points
|
||||||
relatively form MOUNT-POINT/TARGET/SUBDIR/grub.cfg to
|
relatively form MOUNT-POINT/TARGET/SUBDIR/grub.cfg to
|
||||||
MOUNT-POINT/boot/grub/grub.cfg, and the second symlink points relatively from
|
MOUNT-POINT/boot/grub/grub.cfg, and the second symlink points relatively from
|
||||||
MOUNT-POINT/TARGET/%store-prefix to MOUNT-POINT/%store-prefix.
|
MOUNT-POINT/TARGET/%store-prefix to MOUNT-POINT/%store-prefix.
|
||||||
|
@ -739,34 +737,80 @@ (define (install-grub-efi-netboot subdir)
|
||||||
|
|
||||||
It is also important to note that both symlinks will point outside the TFTP root
|
It is also important to note that both symlinks will point outside the TFTP root
|
||||||
directory and that the TARGET/%store-prefix symlink makes the whole store
|
directory and that the TARGET/%store-prefix symlink makes the whole store
|
||||||
accessible via TFTP. Possibly the TFTP server must be configured
|
accessible via TFTP. Possibly the TFTP server must be configured to allow
|
||||||
to allow accesses outside its TFTP root directory. This may need to be
|
accesses outside its TFTP root directory. This all may need to be considered
|
||||||
considered for security aspects."
|
for security aspects. It is advised to disable any TFTP write access!
|
||||||
(use-modules ((guix build union) #:select (symlink-relative)))
|
|
||||||
(let* ((net-dir (string-append mount-point target "/"))
|
The installer can also be used to prepare booting from local storage, if the
|
||||||
(sub-dir (string-append net-dir #$subdir "/"))
|
underlying file-system, like FAT on an EFI System Partition (ESP), does not
|
||||||
(store (string-append mount-point (%store-prefix)))
|
support symlinks. In this case the MOUNT-POINT/TARGET/SUBDIR/grub.cfg will be
|
||||||
(store-link (string-append net-dir (%store-prefix)))
|
created with the help of GRUB-EFI to load the /boot/grub/grub.cfg file. A
|
||||||
(grub-cfg (string-append mount-point "/boot/grub/grub.cfg"))
|
symlink to the store is not needed in this case."
|
||||||
(grub-cfg-link (string-append sub-dir (basename grub-cfg)))
|
(with-imported-modules '((guix build union))
|
||||||
(boot-efi-link (string-append sub-dir #$boot-efi-link)))
|
#~(lambda (bootloader target mount-point)
|
||||||
;; Prepare the symlink to the store.
|
;; In context of a disk image creation TARGET will be #f and an
|
||||||
(mkdir-p (dirname store-link))
|
;; installer is expected to do necessary installations on MOUNT-POINT,
|
||||||
(false-if-exception (delete-file store-link))
|
;; which will become the root file system. If TARGET is #f, this
|
||||||
(symlink-relative store store-link)
|
;; installer has nothing to do, as it only cares about the EFI System
|
||||||
;; Prepare the symlink to the grub.cfg, which points into the store.
|
;; Partition (ESP).
|
||||||
(mkdir-p (dirname grub-cfg-link))
|
(when target
|
||||||
(false-if-exception (delete-file grub-cfg-link))
|
(use-modules ((guix build union) #:select (symlink-relative))
|
||||||
(symlink-relative grub-cfg grub-cfg-link)
|
(ice-9 popen)
|
||||||
;; Install GRUB, which refers to the grub.cfg, with support for
|
(ice-9 rdelim))
|
||||||
;; encrypted partitions,
|
(let* ((mount-point/target (string-append mount-point target "/"))
|
||||||
(setenv "GRUB_ENABLE_CRYPTODISK" "y")
|
;; When installing Guix, it is common to mount TARGET below
|
||||||
(invoke/quiet (string-append bootloader "/bin/grub-mknetdir")
|
;; MOUNT-POINT rather than the root directory.
|
||||||
(string-append "--net-directory=" net-dir)
|
(bootloader-target (if (file-exists? mount-point/target)
|
||||||
(string-append "--subdir=" #$subdir))
|
mount-point/target
|
||||||
;; Prepare the bootloader symlink, which points to core.efi of GRUB.
|
target))
|
||||||
(false-if-exception (delete-file boot-efi-link))
|
(store (string-append mount-point (%store-prefix)))
|
||||||
(symlink #$core-efi boot-efi-link))))))
|
(store-link (string-append bootloader-target (%store-prefix)))
|
||||||
|
(grub-cfg (string-append mount-point #$grub-cfg))
|
||||||
|
(grub-cfg-link (string-append bootloader-target
|
||||||
|
#$subdir "/"
|
||||||
|
(basename grub-cfg))))
|
||||||
|
;; Copy the bootloader into the bootloader-target directory.
|
||||||
|
;; Should we beforehand recursively delete any existing file?
|
||||||
|
(copy-recursively bootloader bootloader-target
|
||||||
|
#:follow-symlinks? #t
|
||||||
|
#:log (%make-void-port "w"))
|
||||||
|
;; For TFTP we need to install additional relative symlinks.
|
||||||
|
;; If we install on an EFI System Partition (ESP) or some other FAT
|
||||||
|
;; file-system, then symlinks cannot be created and are not needed.
|
||||||
|
;; Therefore we ignore exceptions when trying.
|
||||||
|
;; Prepare the symlink to the grub.cfg.
|
||||||
|
(mkdir-p (dirname grub-cfg-link))
|
||||||
|
(false-if-exception (delete-file grub-cfg-link))
|
||||||
|
(if (unspecified?
|
||||||
|
(false-if-exception (symlink-relative grub-cfg grub-cfg-link)))
|
||||||
|
;; Symlinks are supported.
|
||||||
|
(begin
|
||||||
|
;; Prepare the symlink to the store.
|
||||||
|
(mkdir-p (dirname store-link))
|
||||||
|
(false-if-exception (delete-file store-link))
|
||||||
|
(symlink-relative store store-link))
|
||||||
|
;; Creating symlinks does not seem to be supported. Probably
|
||||||
|
;; an ESP is used. Add a script to search and load the actual
|
||||||
|
;; grub.cfg.
|
||||||
|
(let* ((probe #$(file-append grub-efi "/sbin/grub-probe"))
|
||||||
|
(port (open-pipe* OPEN_READ probe "--target=fs_uuid"
|
||||||
|
grub-cfg))
|
||||||
|
(search-root
|
||||||
|
(match (read-line port)
|
||||||
|
((? eof-object?)
|
||||||
|
;; There is no UUID available. As a fallback search
|
||||||
|
;; everywhere for the grub.cfg.
|
||||||
|
(string-append "search --file --set " #$grub-cfg))
|
||||||
|
(fs-uuid
|
||||||
|
;; The UUID to load the grub.cfg from is known.
|
||||||
|
(string-append "search --fs-uuid --set " fs-uuid))))
|
||||||
|
(load-grub-cfg (string-append "configfile " #$grub-cfg)))
|
||||||
|
(close-pipe port)
|
||||||
|
(with-output-to-file grub-cfg-link
|
||||||
|
(lambda ()
|
||||||
|
(display (string-join (list search-root
|
||||||
|
load-grub-cfg)
|
||||||
|
"\n")))))))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -784,7 +828,7 @@ (define grub-bootloader
|
||||||
(package grub)
|
(package grub)
|
||||||
(installer install-grub)
|
(installer install-grub)
|
||||||
(disk-image-installer install-grub-disk-image)
|
(disk-image-installer install-grub-disk-image)
|
||||||
(configuration-file "/boot/grub/grub.cfg")
|
(configuration-file grub-cfg)
|
||||||
(configuration-file-generator grub-configuration-file)))
|
(configuration-file-generator grub-configuration-file)))
|
||||||
|
|
||||||
(define grub-minimal-bootloader
|
(define grub-minimal-bootloader
|
||||||
|
@ -794,11 +838,12 @@ (define grub-minimal-bootloader
|
||||||
|
|
||||||
(define grub-efi-bootloader
|
(define grub-efi-bootloader
|
||||||
(bootloader
|
(bootloader
|
||||||
(inherit grub-bootloader)
|
(name 'grub-efi)
|
||||||
|
(package grub-efi)
|
||||||
(installer install-grub-efi)
|
(installer install-grub-efi)
|
||||||
(disk-image-installer #f)
|
(disk-image-installer #f)
|
||||||
(name 'grub-efi)
|
(configuration-file grub-cfg)
|
||||||
(package grub-efi)))
|
(configuration-file-generator grub-configuration-file)))
|
||||||
|
|
||||||
(define grub-efi-removable-bootloader
|
(define grub-efi-removable-bootloader
|
||||||
(bootloader
|
(bootloader
|
||||||
|
@ -813,11 +858,22 @@ (define grub-efi32-bootloader
|
||||||
(name 'grub-efi32)
|
(name 'grub-efi32)
|
||||||
(package grub-efi32)))
|
(package grub-efi32)))
|
||||||
|
|
||||||
(define grub-efi-netboot-bootloader
|
(define (make-grub-efi-netboot-bootloader name subdir)
|
||||||
(bootloader
|
(bootloader
|
||||||
(inherit grub-efi-bootloader)
|
(name name)
|
||||||
(name 'grub-efi-netboot-bootloader)
|
(package (make-grub-efi-netboot (symbol->string name) subdir))
|
||||||
(installer (install-grub-efi-netboot "efi/Guix"))))
|
(installer (make-grub-efi-netboot-installer grub-efi grub-cfg subdir))
|
||||||
|
(disk-image-installer #f)
|
||||||
|
(configuration-file grub-cfg)
|
||||||
|
(configuration-file-generator grub-efi-configuration-file)))
|
||||||
|
|
||||||
|
(define grub-efi-netboot-bootloader
|
||||||
|
(make-grub-efi-netboot-bootloader 'grub-efi-netboot-bootloader
|
||||||
|
"efi/Guix"))
|
||||||
|
|
||||||
|
(define grub-efi-netboot-removable-bootloader
|
||||||
|
(make-grub-efi-netboot-bootloader 'grub-efi-netboot-removable-bootloader
|
||||||
|
"efi/boot"))
|
||||||
|
|
||||||
(define grub-mkrescue-bootloader
|
(define grub-mkrescue-bootloader
|
||||||
(bootloader
|
(bootloader
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
;;; Copyright © 2021 Vincent Legoll <vincent.legoll@gmail.com>
|
;;; Copyright © 2021 Vincent Legoll <vincent.legoll@gmail.com>
|
||||||
;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re>
|
;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re>
|
||||||
;;; Copyright © 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
|
;;; Copyright © 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
|
||||||
|
;;; Copyright © 2021 Stefan <stefan-guix@vodafonemail.de>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -67,7 +68,9 @@ (define-module (gnu packages bootloaders)
|
||||||
#:use-module (gnu packages virtualization)
|
#:use-module (gnu packages virtualization)
|
||||||
#:use-module (gnu packages xorg)
|
#:use-module (gnu packages xorg)
|
||||||
#:use-module (guix build-system gnu)
|
#:use-module (guix build-system gnu)
|
||||||
|
#:use-module (guix build-system trivial)
|
||||||
#:use-module (guix download)
|
#:use-module (guix download)
|
||||||
|
#:use-module (guix gexp)
|
||||||
#:use-module (guix git-download)
|
#:use-module (guix git-download)
|
||||||
#:use-module ((guix licenses) #:prefix license:)
|
#:use-module ((guix licenses) #:prefix license:)
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
|
@ -75,6 +78,7 @@ (define-module (gnu packages bootloaders)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-26)
|
#:use-module (srfi srfi-26)
|
||||||
#:use-module (ice-9 optargs)
|
#:use-module (ice-9 optargs)
|
||||||
|
#:use-module (ice-9 match)
|
||||||
#:use-module (ice-9 regex))
|
#:use-module (ice-9 regex))
|
||||||
|
|
||||||
(define unifont
|
(define unifont
|
||||||
|
@ -390,6 +394,92 @@ (define-public grub-hybrid
|
||||||
(scandir input-dir))
|
(scandir input-dir))
|
||||||
#t)))))))))
|
#t)))))))))
|
||||||
|
|
||||||
|
(define-public (make-grub-efi-netboot name subdir)
|
||||||
|
"Make a grub-efi-netboot package named NAME, which will be able to boot over
|
||||||
|
network via TFTP by accessing its files in the SUBDIR of a TFTP root directory.
|
||||||
|
This package is also able to boot from local storage devices.
|
||||||
|
|
||||||
|
A bootloader-installer basically needs to copy the package content into the
|
||||||
|
bootloader-target directory, which will usually be the TFTP root, as
|
||||||
|
'grub-mknetdir' will be invoked already during the package creation.
|
||||||
|
|
||||||
|
Alternatively the bootloader-target directory can be a mounted EFI System
|
||||||
|
Partition (ESP), or a similar partition with a FAT file system, for booting
|
||||||
|
from local storage devices.
|
||||||
|
|
||||||
|
The name of the GRUB EFI binary will conform to the UEFI specification for
|
||||||
|
removable media. Depending on the system it will be e.g. bootx64.efi or
|
||||||
|
bootaa64.efi below SUBDIR.
|
||||||
|
|
||||||
|
The SUBDIR argument needs to be set to \"efi/boot\" to create a package which
|
||||||
|
conforms to the UEFI specification for removable media.
|
||||||
|
|
||||||
|
The SUBDIR argument defaults to \"efi/Guix\", as it is also the case for
|
||||||
|
'grub-efi-bootloader'."
|
||||||
|
(package
|
||||||
|
(name name)
|
||||||
|
(version (package-version grub-efi))
|
||||||
|
;; Source is not needed, but it cannot be omitted.
|
||||||
|
(source #f)
|
||||||
|
(build-system trivial-build-system)
|
||||||
|
(arguments
|
||||||
|
(let* ((system (string-split (nix-system->gnu-triplet
|
||||||
|
(or (%current-target-system)
|
||||||
|
(%current-system)))
|
||||||
|
#\-))
|
||||||
|
(arch (first system))
|
||||||
|
(boot-efi
|
||||||
|
(match system
|
||||||
|
;; These are the supportend systems and the names defined by
|
||||||
|
;; the UEFI standard for removable media.
|
||||||
|
(("i686" _ ...) "/bootia32.efi")
|
||||||
|
(("x86_64" _ ...) "/bootx64.efi")
|
||||||
|
(("arm" _ ...) "/bootarm.efi")
|
||||||
|
(("aarch64" _ ...) "/bootaa64.efi")
|
||||||
|
(("riscv" _ ...) "/bootriscv32.efi")
|
||||||
|
(("riscv64" _ ...) "/bootriscv64.efi")
|
||||||
|
;; Other systems are not supported, although defined.
|
||||||
|
;; (("riscv128" _ ...) "/bootriscv128.efi")
|
||||||
|
;; (("ia64" _ ...) "/bootia64.efi")
|
||||||
|
((_ ...) #f)))
|
||||||
|
(core-efi (string-append
|
||||||
|
;; This is the arch dependent file name of GRUB, e.g.
|
||||||
|
;; i368-efi/core.efi or arm64-efi/core.efi.
|
||||||
|
(match arch
|
||||||
|
("i686" "i386")
|
||||||
|
("aarch64" "arm64")
|
||||||
|
("riscv" "riscv32")
|
||||||
|
(_ arch))
|
||||||
|
"-efi/core.efi")))
|
||||||
|
(list
|
||||||
|
#:modules '((guix build utils))
|
||||||
|
#:builder
|
||||||
|
#~(begin
|
||||||
|
(use-modules (guix build utils))
|
||||||
|
(let* ((bootloader #$(this-package-input "grub-efi"))
|
||||||
|
(net-dir #$output)
|
||||||
|
(sub-dir (string-append net-dir "/" #$subdir "/"))
|
||||||
|
(boot-efi (string-append sub-dir #$boot-efi))
|
||||||
|
(core-efi (string-append sub-dir #$core-efi)))
|
||||||
|
;; Install GRUB, which refers to the grub.cfg, with support for
|
||||||
|
;; encrypted partitions,
|
||||||
|
(setenv "GRUB_ENABLE_CRYPTODISK" "y")
|
||||||
|
(invoke/quiet (string-append bootloader "/bin/grub-mknetdir")
|
||||||
|
(string-append "--net-directory=" net-dir)
|
||||||
|
(string-append "--subdir=" #$subdir)
|
||||||
|
;; These modules must be pre-loaded to allow booting
|
||||||
|
;; from an ESP or a similar partition with a FAT
|
||||||
|
;; file system.
|
||||||
|
(string-append "--modules=part_msdos part_gpt fat"))
|
||||||
|
;; Move GRUB's core.efi to the removable media name.
|
||||||
|
(false-if-exception (delete-file boot-efi))
|
||||||
|
(rename-file core-efi boot-efi))))))
|
||||||
|
(inputs (list grub-efi))
|
||||||
|
(synopsis (package-synopsis grub-efi))
|
||||||
|
(description (package-description grub-efi))
|
||||||
|
(home-page (package-home-page grub-efi))
|
||||||
|
(license (package-license grub-efi))))
|
||||||
|
|
||||||
(define-public syslinux
|
(define-public syslinux
|
||||||
(let ((commit "bb41e935cc83c6242de24d2271e067d76af3585c"))
|
(let ((commit "bb41e935cc83c6242de24d2271e067d76af3585c"))
|
||||||
(package
|
(package
|
||||||
|
|
Loading…
Reference in a new issue