gnu: guile-simple-zmq: Update to 0.0.0-10.ff0b39a.
[jackhill/guix/guix.git] / gnu / build / bootloader.scm
CommitLineData
e2248203
MO
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
f0cc5e7e 3;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org>
62c86c83
DGC
4;;; Copyright © 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
5;;; Copyright © 2022 Timothy Sample <samplet@ngyro.com>
e2248203
MO
6;;;
7;;; This file is part of GNU Guix.
8;;;
9;;; GNU Guix is free software; you can redistribute it and/or modify it
10;;; under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 3 of the License, or (at
12;;; your option) any later version.
13;;;
14;;; GNU Guix is distributed in the hope that it will be useful, but
15;;; WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
21
22(define-module (gnu build bootloader)
f8fd1157
MO
23 #:use-module (guix build utils)
24 #:use-module (guix utils)
e2248203 25 #:use-module (ice-9 binary-ports)
f8fd1157 26 #:use-module (ice-9 format)
b97b423e
MO
27 #:use-module (rnrs io ports)
28 #:use-module (rnrs io simple)
f8fd1157
MO
29 #:export (write-file-on-device
30 install-efi-loader))
e2248203
MO
31
32\f
33;;;
34;;; Writing utils.
35;;;
36
37(define (write-file-on-device file size device offset)
38 "Write SIZE bytes from FILE to DEVICE starting at OFFSET."
39 (call-with-input-file file
40 (lambda (input)
41 (let ((bv (get-bytevector-n input size)))
b97b423e 42 (call-with-port
a38d861e 43 ;; Do not use "call-with-output-file" that would truncate the file.
b97b423e 44 (open-file-output-port device
a38d861e 45 (file-options no-truncate no-fail)
b97b423e 46 (buffer-mode block)
a38d861e
MO
47 ;; Use the binary-friendly ISO-8859-1
48 ;; encoding.
49 (make-transcoder (latin-1-codec)))
b97b423e
MO
50 (lambda (output)
51 (seek output offset SEEK_SET)
52 (put-bytevector output bv)))))))
f8fd1157
MO
53
54\f
55;;;
56;;; EFI bootloader.
57;;;
58
62c86c83
DGC
59(define* (install-efi grub grub-config esp #:key targets)
60 "Write a self-contained GRUB EFI loader to the mounted ESP using
61GRUB-CONFIG.
62
63If TARGETS is set, use its car as the GRUB image format and its cdr as
64the output filename. Otherwise, use defaults for the host platform."
f8fd1157
MO
65 (let* ((system %host-type)
66 ;; Hard code the output location to a well-known path recognized by
67 ;; compliant firmware. See "3.5.1.1 Removable Media Boot Behaviour":
68 ;; http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_6.pdf
69 (grub-mkstandalone (string-append grub "/bin/grub-mkstandalone"))
70 (efi-directory (string-append esp "/EFI/BOOT"))
71 ;; Map grub target names to boot file names.
62c86c83
DGC
72 (efi-targets (or targets
73 (cond ((string-prefix? "x86_64" system)
74 '("x86_64-efi" . "BOOTX64.EFI"))
75 ((string-prefix? "i686" system)
76 '("i386-efi" . "BOOTIA32.EFI"))
77 ((string-prefix? "armhf" system)
78 '("arm-efi" . "BOOTARM.EFI"))
79 ((string-prefix? "aarch64" system)
80 '("arm64-efi" . "BOOTAA64.EFI"))))))
f8fd1157
MO
81 ;; grub-mkstandalone requires a TMPDIR to prepare the firmware image.
82 (setenv "TMPDIR" esp)
83
84 (mkdir-p efi-directory)
85 (invoke grub-mkstandalone "-O" (car efi-targets)
86 "-o" (string-append efi-directory "/"
87 (cdr efi-targets))
88 ;; Graft the configuration file onto the image.
89 (string-append "boot/grub/grub.cfg=" grub-config))))
90
62c86c83 91(define* (install-efi-loader grub-efi esp #:key targets)
f8fd1157 92 "Install in ESP directory the given GRUB-EFI bootloader. Configure it to
62c86c83
DGC
93load the Grub bootloader located in the 'Guix_image' root partition.
94
95If TARGETS is set, use its car as the GRUB image format and its cdr as
96the output filename. Otherwise, use defaults for the host platform."
f8fd1157
MO
97 (let ((grub-config "grub.cfg"))
98 (call-with-output-file grub-config
99 (lambda (port)
100 ;; Create a tiny configuration file telling the embedded grub where to
101 ;; load the real thing. XXX This is quite fragile, and can prevent
102 ;; the image from booting when there's more than one volume with this
103 ;; label present. Reproducible almost-UUIDs could reduce the risk
104 ;; (not eliminate it).
105 (format port
106 "insmod part_msdos~@
fb3df201 107 insmod part_gpt~@
f8fd1157
MO
108 search --set=root --label Guix_image~@
109 configfile /boot/grub/grub.cfg~%")))
62c86c83 110 (install-efi grub-efi grub-config esp #:targets targets)
f8fd1157 111 (delete-file grub-config)))
62c86c83 112