[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
01/01: vm: Add UEFI loader to disk images.
From: |
Marius Bakke |
Subject: |
01/01: vm: Add UEFI loader to disk images. |
Date: |
Sat, 20 May 2017 05:22:50 -0400 (EDT) |
mbakke pushed a commit to branch version-0.13.0
in repository guix.
commit 6520904b3e79a5f59bd681931d0ae72783e43eee
Author: Marius Bakke <address@hidden>
Date: Sun May 7 15:31:30 2017 +0200
vm: Add UEFI loader to disk images.
* gnu/build/vm.scm (install-efi): New procedure.
(initialize-hard-disk): Generate EFI blob when ESP is present.
* gnu/system/vm.scm (qemu-image): Append 40MiB EFI System Partition.
(cherry picked from commit ecf5d5376979fadd971559367bf553df89fcc62b)
---
gnu/build/vm.scm | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
gnu/system/vm.scm | 20 ++++++++++++++++---
2 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm
index ef8dcc3..7147ce1 100644
--- a/gnu/build/vm.scm
+++ b/gnu/build/vm.scm
@@ -27,6 +27,7 @@
#:use-module (gnu build linux-boot)
#:use-module (gnu build install)
#:use-module (guix records)
+ #:use-module (ice-9 format)
#:use-module (ice-9 match)
#:use-module (ice-9 regex)
#:use-module (srfi srfi-1)
@@ -315,9 +316,38 @@ SYSTEM-DIRECTORY is the name of the directory of the
'system' derivation."
(mkdir-p directory)
(symlink bootcfg (string-append directory "/grub.cfg"))))
+(define (install-efi grub esp config-file)
+ "Write a self-contained GRUB EFI loader to the mounted ESP using
CONFIG-FILE."
+ (let* ((system %host-type)
+ ;; Hard code the output location to a well-known path recognized by
+ ;; compliant firmware. See "3.5.1.1 Removable Media Boot Behaviour":
+ ;;
http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_6.pdf
+ (grub-mkstandalone (string-append grub "/bin/grub-mkstandalone"))
+ (efi-directory (string-append esp "/EFI/BOOT"))
+ ;; Map grub target names to boot file names.
+ (efi-targets (cond ((string-prefix? "x86_64" system)
+ '("x86_64-efi" . "BOOTX64.EFI"))
+ ((string-prefix? "i686" system)
+ '("i386-efi" . "BOOTIA32.EFI"))
+ ((string-prefix? "armhf" system)
+ '("arm-efi" . "BOOTARM.EFI"))
+ ((string-prefix? "aarch64" system)
+ '("arm64-efi" . "BOOTAA64.EFI")))))
+ ;; grub-mkstandalone requires a TMPDIR to prepare the firmware image.
+ (setenv "TMPDIR" esp)
+
+ (mkdir-p efi-directory)
+ (unless (zero? (system* grub-mkstandalone "-O" (car efi-targets)
+ "-o" (string-append efi-directory "/"
+ (cdr efi-targets))
+ ;; Graft the configuration file onto the image.
+ (string-append "boot/grub/grub.cfg=" config-file)))
+ (error "failed to create GRUB EFI image"))))
+
(define* (initialize-hard-disk device
#:key
grub.cfg
+ (grub-efi #f)
(partitions '()))
"Initialize DEVICE as a disk containing all the <partition> objects listed
in PARTITIONS, and using BOOTCFG as its bootloader configuration file.
@@ -329,8 +359,13 @@ passing it a directory name where it is mounted."
"Return the first partition found with the boot flag set."
(member 'boot (partition-flags partition)))
+ (define (partition-esp? partition)
+ "Return the first EFI System Partition."
+ (member 'esp (partition-flags partition)))
+
(let* ((partitions (initialize-partition-table device partitions))
(root (find partition-bootable? partitions))
+ (esp (find partition-esp? partitions))
(target "/fs"))
(unless root
(error "no bootable partition specified" partitions))
@@ -342,6 +377,31 @@ passing it a directory name where it is mounted."
(mount (partition-device root) target (partition-file-system root))
(install-grub grub.cfg device target)
+ (when esp
+ ;; Mount the ESP somewhere and install GRUB UEFI image.
+ (let ((mount-point (string-append target "/boot/efi"))
+ (grub-config (string-append target "/tmp/grub-standalone.cfg")))
+ (display "mounting EFI system partition...\n")
+ (mkdir-p mount-point)
+ (mount (partition-device esp) mount-point
+ (partition-file-system esp))
+
+ ;; Create a tiny configuration file telling the embedded grub
+ ;; where to load the real thing.
+ (call-with-output-file grub-config
+ (lambda (port)
+ (format port
+ "insmod part_msdos~@
+ search --set=root --label gnu-disk-image~@
+ configfile /boot/grub/grub.cfg~%")))
+
+ (display "creating EFI firmware image...")
+ (install-efi grub-efi mount-point grub-config)
+ (display "done.\n")
+
+ (delete-file grub-config)
+ (umount mount-point)))
+
;; Register GRUB.CFG as a GC root.
(register-grub.cfg-root target grub.cfg)
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index 2110ce6..c40bb4c 100644
--- a/gnu/system/vm.scm
+++ b/gnu/system/vm.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2016 Christopher Allan Webber <address@hidden>
;;; Copyright © 2016 Leo Famulari <address@hidden>
;;; Copyright © 2017 Mathieu Othacehe <address@hidden>
+;;; Copyright © 2017 Marius Bakke <address@hidden>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -226,14 +227,27 @@ the image."
#:system-directory #$os-derivation))
(partitions (list (partition
(size #$(- disk-image-size
- (* 10 (expt 2 20))))
+ (* 50 (expt 2 20))))
(label #$file-system-label)
(file-system #$file-system-type)
(flags '(boot))
- (initializer initialize)))))
+ (initializer initialize))
+ ;; Append a small EFI System Partition for
+ ;; use with UEFI bootloaders.
+ (partition
+ ;; The standalone grub image is about
10MiB, but
+ ;; leave some room for custom or multiple
images.
+ (size (* 40 (expt 2 20)))
+ (label "GNU-ESP") ;cosmetic
only
+ ;; Use "vfat" here since this property is
used
+ ;; when mounting. The actual FAT-ness is
based
+ ;; on filesystem size (16 in this case).
+ (file-system "vfat")
+ (flags '(esp))))))
(initialize-hard-disk "/dev/vda"
#:partitions partitions
- #:grub.cfg #$grub-configuration)
+ #:grub.cfg #$grub-configuration
+ #:grub-efi #$grub-efi)
(reboot)))))
#:system system
#:make-disk-image? #t