gnu: Add python-vf-1.
[jackhill/guix/guix.git] / gnu / packages / bootloaders.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2015, 2018 Mark H Weaver <mhw@netris.org>
4 ;;; Copyright © 2015 Leo Famulari <leo@famulari.name>
5 ;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
6 ;;; Copyright © 2016, 2017, 2018 Marius Bakke <mbakke@fastmail.com>
7 ;;; Copyright © 2016, 2017 Danny Milosavljevic <dannym@scratchpost.org>
8 ;;; Copyright © 2016, 2017 David Craven <david@craven.ch>
9 ;;; Copyright © 2017, 2018 Efraim Flashner <efraim@flashner.co.il>
10 ;;; Copyright © 2018, 2019 Tobias Geerinckx-Rice <me@tobias.gr>
11 ;;; Copyright © 2019 nee <nee@cock.li>
12 ;;; Copyright © 2019 Mathieu Othacehe <m.othacehe@gmail.com>
13 ;;; Copyright © 2020 Björn Höfling <bjoern.hoefling@bjoernhoefling.de>
14 ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
15 ;;; Copyright © 2018, 2019, 2020 Vagrant Cascadian <vagrant@debian.org>
16 ;;; Copyright © 2020 Pierre Langlois <pierre.langlois@gmx.com>
17 ;;;
18 ;;; This file is part of GNU Guix.
19 ;;;
20 ;;; GNU Guix is free software; you can redistribute it and/or modify it
21 ;;; under the terms of the GNU General Public License as published by
22 ;;; the Free Software Foundation; either version 3 of the License, or (at
23 ;;; your option) any later version.
24 ;;;
25 ;;; GNU Guix is distributed in the hope that it will be useful, but
26 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
27 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 ;;; GNU General Public License for more details.
29 ;;;
30 ;;; You should have received a copy of the GNU General Public License
31 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
32
33 (define-module (gnu packages bootloaders)
34 #:use-module (gnu packages)
35 #:use-module (gnu packages admin)
36 #:use-module (gnu packages algebra)
37 #:use-module (gnu packages assembly)
38 #:use-module (gnu packages base)
39 #:use-module (gnu packages disk)
40 #:use-module (gnu packages bison)
41 #:use-module (gnu packages cdrom)
42 #:use-module (gnu packages check)
43 #:use-module (gnu packages compression)
44 #:use-module (gnu packages cross-base)
45 #:use-module (gnu packages disk)
46 #:use-module (gnu packages firmware)
47 #:use-module (gnu packages flex)
48 #:use-module (gnu packages fontutils)
49 #:use-module (gnu packages gcc)
50 #:use-module (gnu packages gettext)
51 #:use-module (gnu packages linux)
52 #:use-module (gnu packages man)
53 #:use-module (gnu packages mtools)
54 #:use-module (gnu packages ncurses)
55 #:use-module (gnu packages perl)
56 #:use-module (gnu packages pkg-config)
57 #:use-module (gnu packages python)
58 #:use-module (gnu packages texinfo)
59 #:use-module (gnu packages tls)
60 #:use-module (gnu packages sdl)
61 #:use-module (gnu packages swig)
62 #:use-module (gnu packages valgrind)
63 #:use-module (gnu packages virtualization)
64 #:use-module (gnu packages xorg)
65 #:use-module (gnu packages web)
66 #:use-module (guix build-system gnu)
67 #:use-module (guix download)
68 #:use-module (guix git-download)
69 #:use-module ((guix licenses) #:prefix license:)
70 #:use-module (guix packages)
71 #:use-module (guix utils)
72 #:use-module (srfi srfi-1)
73 #:use-module (srfi srfi-26)
74 #:use-module (ice-9 regex))
75
76 (define unifont
77 ;; GNU Unifont, <http://gnu.org/s/unifont>.
78 ;; GRUB needs it for its graphical terminal, gfxterm.
79 (origin
80 (method url-fetch)
81 (uri
82 "http://unifoundry.com/pub/unifont-7.0.06/font-builds/unifont-7.0.06.bdf.gz")
83 (sha256
84 (base32
85 "0p2vhnc18cnbmb39vq4m7hzv4mhnm2l0a2s7gx3ar277fwng3hys"))))
86
87 (define-public grub
88 (package
89 (name "grub")
90 (version "2.04")
91 (source (origin
92 (method url-fetch)
93 (uri (string-append "mirror://gnu/grub/grub-" version ".tar.xz"))
94 (sha256
95 (base32
96 "0zgp5m3hmc9jh8wpjx6czzkh5id2y8n1k823x2mjvm2sk6b28ag5"))
97 (patches (search-patches
98 "grub-efi-fat-serial-number.patch"
99 "grub-verifiers-Blocklist-fallout-cleanup.patch"))))
100 (build-system gnu-build-system)
101 (arguments
102 `(#:configure-flags
103 ;; Counterintuitively, this *disables* a spurious Python dependency by
104 ;; calling the ‘true’ binary instead. Python is only needed during
105 ;; bootstrapping (for genptl.py), not when building from a release.
106 (list "PYTHON=true")
107 #:phases (modify-phases %standard-phases
108 (add-after 'unpack 'patch-stuff
109 (lambda* (#:key native-inputs inputs #:allow-other-keys)
110 (substitute* "grub-core/Makefile.in"
111 (("/bin/sh") (which "sh")))
112
113 ;; Give the absolute file name of 'mdadm', used to
114 ;; determine the root file system when it's a RAID
115 ;; device. Failing to do that, 'grub-probe' silently
116 ;; fails if 'mdadm' is not in $PATH.
117 (substitute* "grub-core/osdep/linux/getroot.c"
118 (("argv\\[0\\] = \"mdadm\"")
119 (string-append "argv[0] = \""
120 (assoc-ref inputs "mdadm")
121 "/sbin/mdadm\"")))
122
123 ;; Make the font visible.
124 (copy-file (assoc-ref (or native-inputs inputs)
125 "unifont")
126 "unifont.bdf.gz")
127 (system* "gunzip" "unifont.bdf.gz")
128
129 ;; Give the absolute file name of 'ckbcomp'.
130 (substitute* "util/grub-kbdcomp.in"
131 (("^ckbcomp ")
132 (string-append (assoc-ref inputs "console-setup")
133 "/bin/ckbcomp ")))
134 #t))
135 (add-before 'check 'disable-flaky-test
136 (lambda _
137 ;; This test is unreliable. For more information, see:
138 ;; <https://bugs.gnu.org/26936>.
139 (substitute* "Makefile.in"
140 (("grub_cmd_date grub_cmd_set_date grub_cmd_sleep")
141 "grub_cmd_date grub_cmd_sleep"))
142 #t))
143 (add-before 'check 'disable-pixel-perfect-test
144 (lambda _
145 ;; This test compares many screenshots rendered with an
146 ;; older Unifont (9.0.06) than that packaged in Guix.
147 (substitute* "Makefile.in"
148 (("test_unset grub_func_test")
149 "test_unset"))
150 #t)))
151 ;; Disable tests on ARM and AARCH64 platforms.
152 #:tests? ,(not (any (cute string-prefix? <> (or (%current-target-system)
153 (%current-system)))
154 '("arm" "aarch64")))))
155 (inputs
156 `(("gettext" ,gettext-minimal)
157
158 ;; Depend on LVM2 for libdevmapper, used by 'grub-probe' and
159 ;; 'grub-install' to recognize mapped devices (LUKS, etc.)
160 ,@(if (member (or (%current-target-system)
161 (%current-system))
162 (package-supported-systems lvm2))
163 `(("lvm2" ,lvm2))
164 '())
165
166 ;; Depend on mdadm, which is invoked by 'grub-probe' and 'grub-install'
167 ;; to determine whether the root file system is RAID.
168 ,@(if (member (or (%current-target-system)
169 (%current-system))
170 (package-supported-systems mdadm))
171 `(("mdadm" ,mdadm))
172 '())
173
174 ;; Console-setup's ckbcomp is invoked by grub-kbdcomp. It is required
175 ;; for generating alternative keyboard layouts.
176 ("console-setup" ,console-setup)
177
178 ;; Needed for ‘grub-mount’, the only reliable way to tell whether a given
179 ;; file system will be readable by GRUB without rebooting.
180 ,@(if (member (or (%current-target-system)
181 (%current-system))
182 (package-supported-systems fuse))
183 `(("fuse" ,fuse))
184 '())
185
186 ("freetype" ,freetype)
187 ;; ("libusb" ,libusb)
188 ("ncurses" ,ncurses)))
189 (native-inputs
190 `(("pkg-config" ,pkg-config)
191 ("unifont" ,unifont)
192 ("bison" ,bison)
193 ("flex" ,flex)
194 ("texinfo" ,texinfo)
195 ("help2man" ,help2man)
196
197 ;; XXX: When building GRUB 2.02 on 32-bit x86, we need a binutils
198 ;; capable of assembling 64-bit instructions. However, our default
199 ;; binutils on 32-bit x86 is not 64-bit capable.
200 ,@(if (string-match "^i[3456]86-" (%current-system))
201 (let ((binutils (package/inherit
202 binutils
203 (name "binutils-i386")
204 (arguments
205 (substitute-keyword-arguments (package-arguments binutils)
206 ((#:configure-flags flags ''())
207 `(cons "--enable-64-bit-bfd" ,flags)))))))
208 `(("ld-wrapper" ,(make-ld-wrapper "ld-wrapper-i386"
209 #:binutils binutils))
210 ("binutils" ,binutils)))
211 '())
212
213 ;; Dependencies for the test suite. The "real" QEMU is needed here,
214 ;; because several targets are used.
215 ("parted" ,parted)
216 ,@(if (member (%current-system) (package-supported-systems qemu-minimal))
217 `(("qemu" ,qemu-minimal))
218 '())
219 ("xorriso" ,xorriso)))
220 (home-page "https://www.gnu.org/software/grub/")
221 (synopsis "GRand Unified Boot loader")
222 (description
223 "GRUB is a multiboot bootloader. It is used for initially loading the
224 kernel of an operating system and then transferring control to it. The kernel
225 then goes on to load the rest of the operating system. As a multiboot
226 bootloader, GRUB handles the presence of multiple operating systems installed
227 on the same computer; upon booting the computer, the user is presented with a
228 menu to select one of the installed operating systems.")
229 (license license:gpl3+)
230 (properties '((cpe-name . "grub2")))))
231
232 (define-public grub-minimal
233 (package
234 (inherit grub)
235 (name "grub-minimal")
236 (inputs
237 (fold alist-delete (package-inputs grub)
238 '("lvm2" "mdadm" "fuse" "console-setup")))
239 (native-inputs
240 (fold alist-delete (package-native-inputs grub)
241 '("help2man" "texinfo" "parted" "qemu" "xorriso")))
242 (arguments
243 `(#:configure-flags (list "PYTHON=true")
244 #:phases (modify-phases %standard-phases
245 (add-after 'unpack 'patch-stuff
246 (lambda* (#:key native-inputs inputs #:allow-other-keys)
247 (substitute* "grub-core/Makefile.in"
248 (("/bin/sh") (which "sh")))
249
250 ;; Make the font visible.
251 (copy-file (assoc-ref (or native-inputs inputs)
252 "unifont")
253 "unifont.bdf.gz")
254 (system* "gunzip" "unifont.bdf.gz")
255
256 #t)))
257 #:tests? #f))))
258
259 (define-public grub-efi
260 (package
261 (inherit grub)
262 (name "grub-efi")
263 (synopsis "GRand Unified Boot loader (UEFI version)")
264 (inputs
265 `(("efibootmgr" ,efibootmgr)
266 ("mtools" ,mtools)
267 ,@(package-inputs grub)))
268 (arguments
269 `(;; TODO: Tests need a UEFI firmware for qemu. There is one at
270 ;; https://github.com/tianocore/edk2/tree/master/OvmfPkg .
271 ;; Search for 'OVMF' in "tests/util/grub-shell.in".
272 ,@(substitute-keyword-arguments (package-arguments grub)
273 ((#:tests? _ #f) #f)
274 ((#:configure-flags flags ''())
275 `(cons "--with-platform=efi" ,flags))
276 ((#:phases phases)
277 `(modify-phases ,phases
278 (add-after 'patch-stuff 'use-absolute-efibootmgr-path
279 (lambda* (#:key inputs #:allow-other-keys)
280 (substitute* "grub-core/osdep/unix/platform.c"
281 (("efibootmgr")
282 (string-append (assoc-ref inputs "efibootmgr")
283 "/sbin/efibootmgr")))
284 #t))
285 (add-after 'patch-stuff 'use-absolute-mtools-path
286 (lambda* (#:key inputs #:allow-other-keys)
287 (let ((mtools (assoc-ref inputs "mtools")))
288 (substitute* "util/grub-mkrescue.c"
289 (("\"mformat\"")
290 (string-append "\"" mtools
291 "/bin/mformat\"")))
292 (substitute* "util/grub-mkrescue.c"
293 (("\"mcopy\"")
294 (string-append "\"" mtools
295 "/bin/mcopy\"")))
296 #t))))))))))
297
298 ;; Because grub searches hardcoded paths it's easiest to just build grub
299 ;; again to make it find both grub-pc and grub-efi. There is a command
300 ;; line argument which allows you to specify ONE platform - but
301 ;; grub-mkrescue will use multiple platforms if they are available
302 ;; in the installation directory (without command line argument).
303 (define-public grub-hybrid
304 (package
305 (inherit grub-efi)
306 (name "grub-hybrid")
307 (synopsis "GRand Unified Boot loader (hybrid version)")
308 (inputs
309 `(("grub" ,grub)
310 ,@(package-inputs grub-efi)))
311 (arguments
312 (substitute-keyword-arguments (package-arguments grub-efi)
313 ((#:modules modules `((guix build utils) (guix build gnu-build-system)))
314 `((ice-9 ftw) ,@modules))
315 ((#:phases phases)
316 `(modify-phases ,phases
317 (add-after 'install 'install-non-efi
318 (lambda* (#:key inputs outputs #:allow-other-keys)
319 (let ((input-dir (string-append (assoc-ref inputs "grub")
320 "/lib/grub"))
321 (output-dir (string-append (assoc-ref outputs "out")
322 "/lib/grub")))
323 (for-each
324 (lambda (basename)
325 (if (not (or (string-prefix? "." basename)
326 (file-exists? (string-append output-dir "/" basename))))
327 (symlink (string-append input-dir "/" basename)
328 (string-append output-dir "/" basename))))
329 (scandir input-dir))
330 #t)))))))))
331
332 (define-public syslinux
333 (let ((commit "bb41e935cc83c6242de24d2271e067d76af3585c"))
334 (package
335 (name "syslinux")
336 (version (git-version "6.04-pre" "1" commit))
337 (source (origin
338 (method git-fetch)
339 (uri (git-reference
340 (url "https://github.com/geneC/syslinux")
341 (commit commit)))
342 (file-name (git-file-name name version))
343 (sha256
344 (base32
345 "0k8dvafd6410kqxf3kyr4y8jzmpmrih6wbjqg6gklak7945yflrc"))))
346 (build-system gnu-build-system)
347 (native-inputs
348 `(("nasm" ,nasm)
349 ("perl" ,perl)
350 ("python-2" ,python-2)))
351 (inputs
352 `(("libuuid" ,util-linux "lib")
353 ("mtools" ,mtools)))
354 (arguments
355 `(#:parallel-build? #f
356 #:make-flags
357 (list (string-append "BINDIR=" %output "/bin")
358 (string-append "SBINDIR=" %output "/sbin")
359 (string-append "LIBDIR=" %output "/lib")
360 (string-append "INCDIR=" %output "/include")
361 (string-append "DATADIR=" %output "/share")
362 (string-append "MANDIR=" %output "/share/man")
363 "PERL=perl"
364 "bios")
365 #:phases
366 (modify-phases %standard-phases
367 (add-after 'unpack 'patch-files
368 (lambda* (#:key inputs #:allow-other-keys)
369 (substitute* (find-files "." "Makefile.*|ppmtolss16")
370 (("/bin/pwd") (which "pwd"))
371 (("/bin/echo") (which "echo"))
372 (("/usr/bin/perl") (which "perl")))
373 (let ((mtools (assoc-ref inputs "mtools")))
374 (substitute* (find-files "." "\\.c$")
375 (("mcopy")
376 (string-append mtools "/bin/mcopy"))
377 (("mattrib")
378 (string-append mtools "/bin/mattrib"))))
379 #t))
380 (delete 'configure)
381 (add-before 'build 'set-permissions
382 (lambda _
383 (invoke "chmod" "a+w" "utils/isohybrid.in")))
384 (replace 'check
385 (lambda _
386 (setenv "CC" "gcc")
387 (substitute* "tests/unittest/include/unittest/unittest.h"
388 ;; Don't look up headers under /usr.
389 (("/usr/include/") ""))
390 (invoke "make" "unittest"))))))
391 (home-page "https://www.syslinux.org")
392 (synopsis "Lightweight Linux bootloader")
393 (description "Syslinux is a lightweight Linux bootloader.")
394 ;; The Makefile specifically targets i386 and x86_64 using nasm.
395 (supported-systems '("i686-linux" "x86_64-linux"))
396 (license (list license:gpl2+
397 license:bsd-3 ; gnu-efi/*
398 license:bsd-4 ; gnu-efi/inc/* gnu-efi/lib/*
399 ;; Also contains:
400 license:expat license:isc license:zlib)))))
401
402 (define-public dtc
403 (package
404 (name "dtc")
405 (version "1.5.1")
406 (source (origin
407 (method url-fetch)
408 (uri (string-append
409 "mirror://kernel.org/software/utils/dtc/"
410 "dtc-" version ".tar.xz"))
411 (sha256
412 (base32
413 "07q3mdsvl4smbiakriq3hnsyyd0q344lsm306q0kgz4hjq1p82v6"))))
414 (build-system gnu-build-system)
415 (native-inputs
416 `(("bison" ,bison)
417 ("flex" ,flex)
418 ("libyaml" ,libyaml)
419 ("pkg-config" ,pkg-config)
420 ("swig" ,swig)
421 ("valgrind" ,valgrind)))
422 (inputs
423 `(("python" ,python)))
424 (arguments
425 `(#:make-flags
426 (list "CC=gcc"
427
428 ;; /bin/fdt{get,overlay,put} need help finding libfdt.so.1.
429 (string-append "LDFLAGS=-Wl,-rpath="
430 (assoc-ref %outputs "out") "/lib")
431
432 (string-append "PREFIX=" (assoc-ref %outputs "out"))
433 (string-append "SETUP_PREFIX=" (assoc-ref %outputs "out"))
434 "INSTALL=install")
435 #:phases
436 (modify-phases %standard-phases
437 (delete 'configure)))) ; no configure script
438 (home-page "https://www.devicetree.org")
439 (synopsis "Compiles device tree source files")
440 (description "@command{dtc} compiles
441 @uref{http://elinux.org/Device_Tree_Usage, device tree source files} to device
442 tree binary files. These are board description files used by Linux and BSD.")
443 (license license:gpl2+)))
444
445 (define u-boot
446 (package
447 (name "u-boot")
448 (version "2020.04")
449 (source (origin
450 (method url-fetch)
451 (uri (string-append
452 "ftp://ftp.denx.de/pub/u-boot/"
453 "u-boot-" version ".tar.bz2"))
454 (sha256
455 (base32
456 "0wjkasnz87q86hx93inspdjfjsinmxi87bcvj30c773x0fpjlwzy"))))
457 (native-inputs
458 `(("bc" ,bc)
459 ("bison" ,bison)
460 ("dtc" ,dtc)
461 ("flex" ,flex)
462 ("lz4" ,lz4)
463 ("perl" ,perl)
464 ("python" ,python)
465 ("python-coverage" ,python-coverage)
466 ("python-pytest" ,python-pytest)
467 ("sdl2" ,sdl2)
468 ("swig" ,swig)))
469 (build-system gnu-build-system)
470 (home-page "https://www.denx.de/wiki/U-Boot/")
471 (synopsis "ARM bootloader")
472 (description "U-Boot is a bootloader used mostly for ARM boards. It
473 also initializes the boards (RAM etc).")
474 (license license:gpl2+)))
475
476 (define-public u-boot-tools
477 (package
478 (inherit u-boot)
479 (name "u-boot-tools")
480 (arguments
481 `(#:make-flags '("HOSTCC=gcc")
482 #:test-target "tests"
483 #:phases
484 (modify-phases %standard-phases
485 (add-after 'unpack 'patch
486 (lambda* (#:key inputs #:allow-other-keys)
487 (substitute* "Makefile"
488 (("/bin/pwd") (which "pwd"))
489 (("/bin/false") (which "false")))
490 (substitute* "tools/dtoc/fdt_util.py"
491 (("'cc'") "'gcc'"))
492 (substitute* "tools/patman/test_util.py"
493 ;; python*-coverage is simply called coverage in guix.
494 (("%s-coverage") "coverage")
495 ;; XXX Allow for only 99% test coverage.
496 ;; TODO: Find out why that is needed.
497 (("if coverage != '100%':") "if not int(coverage.rstrip('%')) >= 99:"))
498 (substitute* "test/run"
499 ;; Make it easier to find test failures.
500 (("#!/bin/bash") "#!/bin/bash -x")
501 ;; This test would require git.
502 (("\\./tools/patman/patman") (which "true"))
503 ;; FIXME: test fails, needs further investiation
504 (("run_test \"binman\"") ": run_test \"binman\"")
505 ;; FIXME: code coverage not working
506 (("run_test \"binman code coverage\"") ": run_test \"binman code coverage\"")
507 (("run_test \"dtoc code coverage\"") ": run_test \"dtoc code coverage\"")
508 (("run_test \"fdt code coverage\"") ": run_test \"fdt code coverage\"")
509 ;; This test would require internet access.
510 (("\\./tools/buildman/buildman") (which "true")))
511 (substitute* "test/py/tests/test_sandbox_exit.py"
512 (("def test_ctrl_c")
513 "@pytest.mark.skip(reason='Guix has problems with SIGINT')
514 def test_ctrl_c"))
515 ;; Test against the tools being installed rather than tools built
516 ;; for "sandbox" target.
517 (substitute* "test/image/test-imagetools.sh"
518 (("BASEDIR=sandbox") "BASEDIR=."))
519 (for-each (lambda (file)
520 (substitute* file
521 ;; Disable signatures, due to GPL/Openssl
522 ;; license incompatibilities. See
523 ;; https://bugs.gnu.org/34717 for details.
524 (("CONFIG_FIT_SIGNATURE=y") "CONFIG_FIT_SIGNATURE=n")
525 ;; This test requires a sound system, which is un-used
526 ;; in u-boot-tools.
527 (("CONFIG_SOUND=y") "CONFIG_SOUND=n")))
528 (find-files "configs" "sandbox_.*defconfig$|tools-only_defconfig"))
529 #t))
530 (replace 'configure
531 (lambda* (#:key make-flags #:allow-other-keys)
532 (apply invoke "make" "tools-only_defconfig" make-flags)))
533 (replace 'build
534 (lambda* (#:key inputs make-flags #:allow-other-keys)
535 (apply invoke "make" "tools-all" make-flags)))
536 (replace 'install
537 (lambda* (#:key outputs #:allow-other-keys)
538 (let* ((out (assoc-ref outputs "out"))
539 (bin (string-append out "/bin")))
540 (for-each (lambda (name)
541 (install-file name bin))
542 '("tools/netconsole"
543 "tools/jtagconsole"
544 "tools/gen_eth_addr"
545 "tools/gen_ethaddr_crc"
546 "tools/img2srec"
547 "tools/mkenvimage"
548 "tools/dumpimage"
549 "tools/mkimage"
550 "tools/proftool"
551 "tools/fdtgrep"
552 "tools/env/fw_printenv"
553 "tools/sunxi-spl-image-builder"))
554 #t)))
555 (delete 'check)
556 (add-after 'install 'check
557 (lambda* (#:key make-flags test-target #:allow-other-keys)
558 (invoke "test/image/test-imagetools.sh")))
559 ;; Only run full test suite on x86_64 systems, as many tests
560 ;; assume x86_64.
561 ,@(if (string-match "^x86_64-linux"
562 (or (%current-target-system)
563 (%current-system)))
564 '((add-after 'check 'check-x86
565 (lambda* (#:key make-flags test-target #:allow-other-keys)
566 (apply invoke "make" "mrproper" make-flags)
567 (setenv "SDL_VIDEODRIVER" "dummy")
568 (setenv "PAGER" "cat")
569 (apply invoke "make" test-target make-flags))))
570 '()))))
571 (description "U-Boot is a bootloader used mostly for ARM boards. It
572 also initializes the boards (RAM etc). This package provides its
573 board-independent tools.")))
574
575 (define-public (make-u-boot-package board triplet)
576 "Returns a u-boot package for BOARD cross-compiled for TRIPLET."
577 (let ((same-arch? (lambda ()
578 (string=? (%current-system)
579 (gnu-triplet->nix-system triplet)))))
580 (package
581 (inherit u-boot)
582 (name (string-append "u-boot-"
583 (string-replace-substring (string-downcase board)
584 "_" "-")))
585 (native-inputs
586 `(,@(if (not (same-arch?))
587 `(("cross-gcc" ,(cross-gcc triplet))
588 ("cross-binutils" ,(cross-binutils triplet)))
589 `())
590 ,@(package-native-inputs u-boot)))
591 (arguments
592 `(#:modules ((ice-9 ftw)
593 (srfi srfi-1)
594 (guix build utils)
595 (guix build gnu-build-system))
596 #:test-target "test"
597 #:make-flags
598 (list "HOSTCC=gcc"
599 ,@(if (not (same-arch?))
600 `((string-append "CROSS_COMPILE=" ,triplet "-"))
601 '()))
602 #:phases
603 (modify-phases %standard-phases
604 (replace 'configure
605 (lambda* (#:key outputs make-flags #:allow-other-keys)
606 (let ((config-name (string-append ,board "_defconfig")))
607 (if (file-exists? (string-append "configs/" config-name))
608 (apply invoke "make" `(,@make-flags ,config-name))
609 (begin
610 (display "Invalid board name. Valid board names are:"
611 (current-error-port))
612 (let ((suffix-len (string-length "_defconfig"))
613 (entries (scandir "configs")))
614 (for-each (lambda (file-name)
615 (when (string-suffix? "_defconfig" file-name)
616 (format (current-error-port)
617 "- ~A\n"
618 (string-drop-right file-name
619 suffix-len))))
620 (sort entries string-ci<)))
621 (error "Invalid boardname ~s." ,board))))))
622 (replace 'install
623 (lambda* (#:key outputs #:allow-other-keys)
624 (let* ((out (assoc-ref outputs "out"))
625 (libexec (string-append out "/libexec"))
626 (uboot-files (append
627 (remove
628 ;; Those would not be reproducible
629 ;; because of the randomness used
630 ;; to produce them.
631 ;; It's expected that the user will
632 ;; use u-boot-tools to generate them
633 ;; instead.
634 (lambda (name)
635 (string-suffix?
636 "sunxi-spl-with-ecc.bin"
637 name))
638 (find-files "." ".*\\.(bin|efi|img|spl|itb|dtb|rksd)$"))
639 (find-files "." "^(MLO|SPL)$"))))
640 (mkdir-p libexec)
641 (install-file ".config" libexec)
642 ;; Useful for "qemu -kernel".
643 (install-file "u-boot" libexec)
644 (for-each
645 (lambda (file)
646 (let ((target-file (string-append libexec "/" file)))
647 (mkdir-p (dirname target-file))
648 (copy-file file target-file)))
649 uboot-files)
650 #t)))))))))
651
652 (define-public u-boot-vexpress
653 (make-u-boot-package "vexpress_ca9x4" "arm-linux-gnueabihf"))
654
655 (define-public u-boot-malta
656 (make-u-boot-package "malta" "mips64el-linux-gnuabi64"))
657
658 (define-public u-boot-am335x-boneblack
659 (let ((base (make-u-boot-package "am335x_evm" "arm-linux-gnueabihf")))
660 (package
661 (inherit base)
662 (name "u-boot-am335x-boneblack")
663 (description "U-Boot is a bootloader used mostly for ARM boards. It
664 also initializes the boards (RAM etc).
665
666 This U-Boot is built for the BeagleBone Black, which was removed upstream,
667 adjusted from the am335x_evm build with several device trees removed so that
668 it fits within common partitioning schemes.")
669 (arguments
670 (substitute-keyword-arguments (package-arguments base)
671 ((#:phases phases)
672 `(modify-phases ,phases
673 (add-after 'unpack 'patch-defconfig
674 ;; Patch out other devicetrees to build image small enough to
675 ;; fit within typical partitioning schemes where the first
676 ;; partition begins at sector 2048.
677 (lambda _
678 (substitute* "configs/am335x_evm_defconfig"
679 (("CONFIG_OF_LIST=.*$") "CONFIG_OF_LIST=\"am335x-evm am335x-boneblack\"\n"))
680 #t)))))))))
681
682 (define-public u-boot-am335x-evm
683 (make-u-boot-package "am335x_evm" "arm-linux-gnueabihf"))
684
685 (define-public (make-u-boot-sunxi64-package board triplet)
686 (let ((base (make-u-boot-package board triplet)))
687 (package
688 (inherit base)
689 (arguments
690 (substitute-keyword-arguments (package-arguments base)
691 ((#:phases phases)
692 `(modify-phases ,phases
693 (add-after 'unpack 'set-environment
694 (lambda* (#:key native-inputs inputs #:allow-other-keys)
695 (let ((bl31
696 (string-append
697 (assoc-ref (or native-inputs inputs) "firmware")
698 "/bl31.bin")))
699 (setenv "BL31" bl31)
700 ;; This is necessary when we're using the bundled dtc.
701 ;(setenv "PATH" (string-append (getenv "PATH") ":"
702 ; "scripts/dtc"))
703 )
704 #t))))))
705 (native-inputs
706 `(("firmware" ,arm-trusted-firmware-sun50i-a64)
707 ,@(package-native-inputs base))))))
708
709 (define-public u-boot-pine64-plus
710 (make-u-boot-sunxi64-package "pine64_plus" "aarch64-linux-gnu"))
711
712 (define-public u-boot-pine64-lts
713 (make-u-boot-sunxi64-package "pine64-lts" "aarch64-linux-gnu"))
714
715 (define-public u-boot-pinebook
716 (let ((base (make-u-boot-sunxi64-package "pinebook" "aarch64-linux-gnu")))
717 (package
718 (inherit base)
719 (arguments
720 (substitute-keyword-arguments (package-arguments base)
721 ((#:phases phases)
722 `(modify-phases ,phases
723 (add-after 'unpack 'patch-pinebook-config
724 ;; Fix regression with LCD video output introduced in 2020.01
725 ;; https://patchwork.ozlabs.org/patch/1225130/
726 (lambda _
727 (substitute* "configs/pinebook_defconfig"
728 (("CONFIG_VIDEO_BRIDGE_ANALOGIX_ANX6345=y") "CONFIG_VIDEO_BRIDGE_ANALOGIX_ANX6345=y\nCONFIG_VIDEO_BPP32=y"))
729 #t)))))))))
730
731 (define-public u-boot-bananapi-m2-ultra
732 (make-u-boot-package "Bananapi_M2_Ultra" "arm-linux-gnueabihf"))
733
734 (define-public u-boot-a20-olinuxino-lime
735 (make-u-boot-package "A20-OLinuXino-Lime" "arm-linux-gnueabihf"))
736
737 (define-public u-boot-a20-olinuxino-lime2
738 (make-u-boot-package "A20-OLinuXino-Lime2" "arm-linux-gnueabihf"))
739
740 (define-public u-boot-a20-olinuxino-micro
741 (make-u-boot-package "A20-OLinuXino_MICRO" "arm-linux-gnueabihf"))
742
743 (define-public u-boot-nintendo-nes-classic-edition
744 (make-u-boot-package "Nintendo_NES_Classic_Edition" "arm-linux-gnueabihf"))
745
746 (define-public u-boot-wandboard
747 (make-u-boot-package "wandboard" "arm-linux-gnueabihf"))
748
749 (define-public u-boot-mx6cuboxi
750 (make-u-boot-package "mx6cuboxi" "arm-linux-gnueabihf"))
751
752 (define-public u-boot-novena
753 (let ((base (make-u-boot-package "novena" "arm-linux-gnueabihf")))
754 (package
755 (inherit base)
756 (description "U-Boot is a bootloader used mostly for ARM boards. It
757 also initializes the boards (RAM etc).
758
759 This U-Boot is built for Novena. Be advised that this version, contrary
760 to Novena upstream, does not load u-boot.img from the first partition.")
761 (arguments
762 (substitute-keyword-arguments (package-arguments base)
763 ((#:phases phases)
764 `(modify-phases ,phases
765 (add-after 'unpack 'patch-novena-defconfig
766 ;; Patch configuration to disable loading u-boot.img from FAT partition,
767 ;; allowing it to be installed at a device offset.
768 (lambda _
769 (substitute* "configs/novena_defconfig"
770 (("CONFIG_SPL_FS_FAT=y") "# CONFIG_SPL_FS_FAT is not set"))
771 #t)))))))))
772
773 (define-public u-boot-cubieboard
774 (make-u-boot-package "Cubieboard" "arm-linux-gnueabihf"))
775
776 (define-public u-boot-cubietruck
777 (make-u-boot-package "Cubietruck" "arm-linux-gnueabihf"))
778
779 (define-public u-boot-puma-rk3399
780 (let ((base (make-u-boot-package "puma-rk3399" "aarch64-linux-gnu")))
781 (package
782 (inherit base)
783 (arguments
784 (substitute-keyword-arguments (package-arguments base)
785 ((#:phases phases)
786 `(modify-phases ,phases
787 (add-after 'unpack 'set-environment
788 (lambda* (#:key inputs #:allow-other-keys)
789 ;; Need to copy the firmware into u-boot build
790 ;; directory.
791 (copy-file (string-append (assoc-ref inputs "firmware")
792 "/bl31.bin") "bl31-rk3399.bin")
793 (copy-file (string-append (assoc-ref inputs "firmware-m0")
794 "/rk3399m0.bin") "rk3399m0.bin")
795 #t))
796 (add-after 'build 'build-itb
797 (lambda* (#:key make-flags #:allow-other-keys)
798 ;; The u-boot.itb is not built by default.
799 (apply invoke "make" `(,@make-flags ,"u-boot.itb"))))
800 (add-after 'build-itb 'build-rksd
801 (lambda* (#:key inputs #:allow-other-keys)
802 ;; Build Rockchip SD card images.
803 (invoke "./tools/mkimage" "-T" "rksd" "-n" "rk3399" "-d"
804 "spl/u-boot-spl.bin" "u-boot-spl.rksd")))))))
805 (native-inputs
806 `(("firmware" ,arm-trusted-firmware-puma-rk3399)
807 ("firmware-m0" ,rk3399-cortex-m0)
808 ,@(package-native-inputs base))))))
809
810 (define-public u-boot-qemu-riscv64
811 (make-u-boot-package "qemu-riscv64" "riscv64-linux-gnu"))
812
813 (define-public u-boot-qemu-riscv64-smode
814 (let ((base (make-u-boot-package "qemu-riscv64_smode" "riscv64-linux-gnu")))
815 (package
816 (inherit base)
817 (source (origin
818 (inherit (package-source u-boot))
819 (patches
820 (search-patches "u-boot-riscv64-fix-extlinux.patch")))))))
821
822 (define-public u-boot-sifive-fu540
823 (make-u-boot-package "sifive_fu540" "riscv64-linux-gnu"))
824
825 (define-public u-boot-rock64-rk3328
826 (let ((base (make-u-boot-package "rock64-rk3328" "aarch64-linux-gnu")))
827 (package
828 (inherit base)
829 (arguments
830 (substitute-keyword-arguments (package-arguments base)
831 ((#:phases phases)
832 `(modify-phases ,phases
833 (add-after 'unpack 'set-environment
834 (lambda* (#:key inputs #:allow-other-keys)
835 (let ((bl31 (string-append (assoc-ref inputs "firmware")
836 "/bl31.elf")))
837 (setenv "BL31" bl31))
838 #t))))))
839 (native-inputs
840 `(("firmware" ,arm-trusted-firmware-rk3328)
841 ,@(package-native-inputs base))))))
842
843 (define-public u-boot-firefly-rk3399
844 (let ((base (make-u-boot-package "firefly-rk3399" "aarch64-linux-gnu")))
845 (package
846 (inherit base)
847 (arguments
848 (substitute-keyword-arguments (package-arguments base)
849 ((#:phases phases)
850 `(modify-phases ,phases
851 (add-after 'unpack 'set-environment
852 (lambda* (#:key inputs #:allow-other-keys)
853 (setenv "BL31" (string-append (assoc-ref inputs "firmware")
854 "/bl31.elf"))
855 #t))
856 ;; Phases do not succeed on the bl31 ELF.
857 (delete 'strip)
858 (delete 'validate-runpath)))))
859 (native-inputs
860 `(("firmware" ,arm-trusted-firmware-rk3399)
861 ,@(package-native-inputs base))))))
862
863 (define-public u-boot-rockpro64-rk3399
864 (let ((base (make-u-boot-package "rockpro64-rk3399" "aarch64-linux-gnu")))
865 (package
866 (inherit base)
867 (arguments
868 (substitute-keyword-arguments (package-arguments base)
869 ((#:phases phases)
870 `(modify-phases ,phases
871 (add-after 'unpack 'set-environment
872 (lambda* (#:key inputs #:allow-other-keys)
873 (setenv "BL31" (string-append (assoc-ref inputs "firmware")
874 "/bl31.elf"))
875 #t))
876 ;; Phases do not succeed on the bl31 ELF.
877 (delete 'strip)
878 (delete 'validate-runpath)))))
879 (native-inputs
880 `(("firmware" ,arm-trusted-firmware-rk3399)
881 ,@(package-native-inputs base))))))
882
883 (define-public u-boot-pinebook-pro-rk3399
884 (let ((base (make-u-boot-package "pinebook-pro-rk3399" "aarch64-linux-gnu")))
885 (package
886 (inherit base)
887 (source (origin
888 (inherit (package-source u-boot))
889 (patches
890 (search-patches "u-boot-add-boe-nv140fhmn49-display.patch"
891 "u-boot-gpio-keys-binding-cons.patch"
892 "u-boot-leds-common-binding-con.patch"
893 "u-boot-DT-for-Pinebook-Pro.patch"
894 "u-boot-support-Pinebook-Pro-laptop.patch"
895 "u-boot-video-rockchip-fix-build.patch"))))
896 (arguments
897 (substitute-keyword-arguments (package-arguments base)
898 ((#:phases phases)
899 `(modify-phases ,phases
900 (add-after 'unpack 'set-environment
901 (lambda* (#:key inputs #:allow-other-keys)
902 (setenv "BL31" (string-append (assoc-ref inputs "firmware")
903 "/bl31.elf"))
904 #t))
905 ;; Phases do not succeed on the bl31 ELF.
906 (delete 'strip)
907 (delete 'validate-runpath)))))
908 (native-inputs
909 `(("firmware" ,arm-trusted-firmware-rk3399)
910 ,@(package-native-inputs base))))))
911
912 (define-public vboot-utils
913 (package
914 (name "vboot-utils")
915 (version "R63-10032.B")
916 (source (origin
917 ;; XXX: Snapshots are available but changes timestamps every download.
918 (method git-fetch)
919 (uri (git-reference
920 (url (string-append "https://chromium.googlesource.com"
921 "/chromiumos/platform/vboot_reference"))
922 (commit (string-append "release-" version))))
923 (file-name (string-append name "-" version "-checkout"))
924 (sha256
925 (base32
926 "0h0m3l69vp9dr6xrs1p6y7ilkq3jq8jraw2z20kqfv7lvc9l1lxj"))
927 (patches
928 (search-patches "vboot-utils-skip-test-workbuf.patch"
929 "vboot-utils-fix-tests-show-contents.patch"
930 "vboot-utils-fix-format-load-address.patch"))))
931 (build-system gnu-build-system)
932 (arguments
933 `(#:make-flags (list "CC=gcc"
934 ;; On ARM, we must pass "HOST_ARCH=arm" so that the
935 ;; ${HOST_ARCH} and ${ARCH} variables in the makefile
936 ;; match. Otherwise, ${HOST_ARCH} will be assigned
937 ;; "armv7l", the value of `uname -m`, and will not
938 ;; match ${ARCH}, which will make the tests require
939 ;; QEMU for testing.
940 ,@(if (string-prefix? "arm"
941 (or (%current-target-system)
942 (%current-system)))
943 '("HOST_ARCH=arm")
944 '())
945 (string-append "DESTDIR=" (assoc-ref %outputs "out")))
946 #:phases (modify-phases %standard-phases
947 (add-after 'unpack 'patch-hard-coded-paths
948 (lambda* (#:key inputs outputs #:allow-other-keys)
949 (let ((coreutils (assoc-ref inputs "coreutils"))
950 (diffutils (assoc-ref inputs "diffutils")))
951 (substitute* "futility/misc.c"
952 (("/bin/cp") (string-append coreutils "/bin/cp")))
953 (substitute* "tests/bitmaps/TestBmpBlock.py"
954 (("/usr/bin/cmp") (string-append diffutils "/bin/cmp")))
955 (substitute* "vboot_host.pc.in"
956 (("prefix=/usr")
957 (string-append "prefix=" (assoc-ref outputs "out"))))
958 #t)))
959 (delete 'configure)
960 (add-before 'check 'patch-tests
961 (lambda _
962 ;; These tests compare diffs against known-good values.
963 ;; Patch the paths to match those in the build container.
964 (substitute* (find-files "tests/futility/expect_output")
965 (("/mnt/host/source/src/platform/vboot_reference")
966 (string-append "/tmp/guix-build-" ,name "-" ,version
967 ".drv-0/source")))
968 ;; Tests require write permissions to many of these files.
969 (for-each make-file-writable (find-files "tests/futility"))
970 #t))
971 (add-after 'install 'install-devkeys
972 (lambda* (#:key outputs #:allow-other-keys)
973 (let* ((out (assoc-ref outputs "out"))
974 (share (string-append out "/share/vboot-utils")))
975 (copy-recursively "tests/devkeys"
976 (string-append share "/devkeys"))
977 #t))))
978 #:test-target "runtests"))
979 (native-inputs
980 `(("pkg-config" ,pkg-config)
981
982 ;; For tests.
983 ("diffutils" ,diffutils)
984 ("python@2" ,python-2)))
985 (inputs
986 `(("coreutils" ,coreutils)
987 ("libyaml" ,libyaml)
988 ("openssl" ,openssl)
989 ("openssl:static" ,openssl "static")
990 ("util-linux" ,util-linux "lib")))
991 (home-page
992 "https://dev.chromium.org/chromium-os/chromiumos-design-docs/verified-boot")
993 (synopsis "ChromiumOS verified boot utilities")
994 (description
995 "vboot-utils is a collection of tools to facilitate booting of
996 Chrome-branded devices. This includes the @command{cgpt} partitioning
997 program, the @command{futility} and @command{crossystem} firmware management
998 tools, and more.")
999 (license license:bsd-3)))
1000
1001 (define-public os-prober
1002 (package
1003 (name "os-prober")
1004 (version "1.77")
1005 (source
1006 (origin
1007 (method url-fetch)
1008 (uri (string-append "mirror://debian/pool/main/o/os-prober/os-prober_"
1009 version ".tar.xz"))
1010 (sha256
1011 (base32
1012 "0pvhrw4h05n21zw7ig3a3bi8aqdh6zxs0x1znz4g7vhspsps93ld"))))
1013 (build-system gnu-build-system)
1014 (arguments
1015 `(#:modules ((guix build gnu-build-system)
1016 (guix build utils)
1017 (ice-9 regex) ; for string-match
1018 (srfi srfi-26)) ; for cut
1019 #:make-flags (list "CC=gcc")
1020 #:tests? #f ; no tests
1021 #:phases
1022 (modify-phases %standard-phases
1023 (replace 'configure
1024 (lambda* (#:key outputs #:allow-other-keys)
1025 (substitute* (find-files ".")
1026 (("/usr") (assoc-ref outputs "out")))
1027 (substitute* (find-files "." "50mounted-tests$")
1028 (("mkdir") "mkdir -p"))
1029 #t))
1030 (replace 'install
1031 (lambda* (#:key outputs #:allow-other-keys)
1032 (define (find-files-non-recursive directory)
1033 (find-files directory
1034 (lambda (file stat)
1035 (string-match (string-append "^" directory "/[^/]*$")
1036 file))
1037 #:directories? #t))
1038
1039 (let* ((out (assoc-ref outputs "out"))
1040 (bin (string-append out "/bin"))
1041 (lib (string-append out "/lib"))
1042 (share (string-append out "/share")))
1043 (for-each (cut install-file <> bin)
1044 (list "linux-boot-prober" "os-prober"))
1045 (install-file "newns" (string-append lib "/os-prober"))
1046 (install-file "common.sh" (string-append share "/os-prober"))
1047 (install-file "os-probes/mounted/powerpc/20macosx"
1048 (string-append lib "/os-probes/mounted"))
1049 (for-each
1050 (lambda (directory)
1051 (for-each
1052 (lambda (file)
1053 (let ((destination (string-append lib "/" directory
1054 "/" (basename file))))
1055 (mkdir-p (dirname destination))
1056 (copy-recursively file destination)))
1057 (append (find-files-non-recursive (string-append directory "/common"))
1058 (find-files-non-recursive (string-append directory "/x86")))))
1059 (list "os-probes" "os-probes/mounted" "os-probes/init"
1060 "linux-boot-probes" "linux-boot-probes/mounted"))
1061 #t))))))
1062 (home-page "https://joeyh.name/code/os-prober")
1063 (synopsis "Detect other operating systems")
1064 (description "os-prober probes disks on the system for other operating
1065 systems so that they can be added to the bootloader. It also works out how to
1066 boot existing GNU/Linux systems and detects what distribution is installed in
1067 order to add a suitable bootloader menu entry.")
1068 (license license:gpl2+)))