+ (symlink bootcfg (string-append directory "/bootcfg"))))
+
+(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)
+ (invoke 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))))
+
+(define* (make-iso9660-image grub config-file os-drv target
+ #:key (volume-id "GuixSD_image") (volume-uuid #f)
+ register-closures? (closures '()))
+ "Given a GRUB package, creates an iso image as TARGET, using CONFIG-FILE as
+GRUB configuration and OS-DRV as the stuff in it."
+ (let ((grub-mkrescue (string-append grub "/bin/grub-mkrescue"))
+ (target-store (string-append "/tmp/root" (%store-directory))))
+ (populate-root-file-system os-drv "/tmp/root")
+
+ (mount (%store-directory) target-store "" MS_BIND)
+
+ (when register-closures?
+ (display "registering closures...\n")
+ (for-each (lambda (closure)
+ (register-closure
+ "/tmp/root"
+ (string-append "/xchg/" closure)
+ ;; XXX: Using deduplication causes cross device link errors.
+ #:deduplicate? #f))
+ closures))
+
+ (apply invoke
+ `(,grub-mkrescue "-o" ,target
+ ,(string-append "boot/grub/grub.cfg=" config-file)
+ ,(string-append "gnu/store=" os-drv "/..")
+ "etc=/tmp/root/etc"
+ "var=/tmp/root/var"
+ "run=/tmp/root/run"
+ ;; /mnt is used as part of the installation
+ ;; process, as the mount point for the target
+ ;; file system, so create it.
+ "mnt=/tmp/root/mnt"
+ "--"
+ "-volid" ,(string-upcase volume-id)
+ ,@(if volume-uuid
+ `("-volume_date" "uuid"
+ ,(string-filter (lambda (value)
+ (not (char=? #\- value)))
+ (iso9660-uuid->string
+ volume-uuid)))
+ `())))))