summaryrefslogtreecommitdiff
path: root/gnu/bootloader/grub.scm
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/bootloader/grub.scm')
-rw-r--r--gnu/bootloader/grub.scm220
1 files changed, 138 insertions, 82 deletions
diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scm
index 72832573547..aab766fd6ca 100644
--- a/gnu/bootloader/grub.scm
+++ b/gnu/bootloader/grub.scm
@@ -53,13 +53,14 @@
53 grub-theme-gfxmode 53 grub-theme-gfxmode
54 54
55 install-grub-efi-removable 55 install-grub-efi-removable
56 install-grub-efi-netboot 56 make-grub-efi-netboot-installer
57 57
58 grub-bootloader 58 grub-bootloader
59 grub-efi-bootloader 59 grub-efi-bootloader
60 grub-efi-removable-bootloader 60 grub-efi-removable-bootloader
61 grub-efi32-bootloader 61 grub-efi32-bootloader
62 grub-efi-netboot-bootloader 62 grub-efi-netboot-bootloader
63 grub-efi-netboot-removable-bootloader
63 grub-mkrescue-bootloader 64 grub-mkrescue-bootloader
64 grub-minimal-bootloader 65 grub-minimal-bootloader
65 66
@@ -353,7 +354,7 @@ code."
353 ((or #f (? string?)) 354 ((or #f (? string?))
354 #~(format #f "search --file --set ~a" #$file))))) 355 #~(format #f "search --file --set ~a" #$file)))))
355 356
356(define* (grub-configuration-file config entries 357(define* (make-grub-configuration grub config entries
357 #:key 358 #:key
358 (locale #f) 359 (locale #f)
359 (system (%current-system)) 360 (system (%current-system))
@@ -453,9 +454,7 @@ menuentry ~s {
453 (define locale-config 454 (define locale-config
454 (let* ((entry (first all-entries)) 455 (let* ((entry (first all-entries))
455 (device (menu-entry-device entry)) 456 (device (menu-entry-device entry))
456 (mount-point (menu-entry-device-mount-point entry)) 457 (mount-point (menu-entry-device-mount-point entry)))
457 (bootloader (bootloader-configuration-bootloader config))
458 (grub (bootloader-package bootloader)))
459 #~(let ((locale #$(and locale 458 #~(let ((locale #$(and locale
460 (locale-definition-source 459 (locale-definition-source
461 (locale-name->definition locale)))) 460 (locale-name->definition locale))))
@@ -481,8 +480,6 @@ set lang=~a~%"
481 480
482 (define keyboard-layout-config 481 (define keyboard-layout-config
483 (let* ((layout (bootloader-configuration-keyboard-layout config)) 482 (let* ((layout (bootloader-configuration-keyboard-layout config))
484 (grub (bootloader-package
485 (bootloader-configuration-bootloader config)))
486 (keymap* (and layout 483 (keymap* (and layout
487 (keyboard-layout-file layout #:grub grub))) 484 (keyboard-layout-file layout #:grub grub)))
488 (entry (first all-entries)) 485 (entry (first all-entries))
@@ -533,6 +530,16 @@ fi~%"))))
533 #:options '(#:local-build? #t 530 #:options '(#:local-build? #t
534 #:substitutable? #f))) 531 #:substitutable? #f)))
535 532
533(define (grub-configuration-file config . args)
534 (let* ((bootloader (bootloader-configuration-bootloader config))
535 (grub (bootloader-package bootloader)))
536 (apply make-grub-configuration grub config args)))
537
538(define (grub-efi-configuration-file . args)
539 (apply make-grub-configuration grub-efi args))
540
541(define grub-cfg "/boot/grub/grub.cfg")
542
536 543
537 544
538;;; 545;;;
@@ -674,42 +681,31 @@ fi~%"))))
674 ((target-arm?) "--target=arm-efi")) 681 ((target-arm?) "--target=arm-efi"))
675 "--efi-directory" target-esp))))) 682 "--efi-directory" target-esp)))))
676 683
677(define (install-grub-efi-netboot subdir) 684(define* (make-grub-efi-netboot-installer grub-efi grub-cfg subdir)
678 "Define a grub-efi-netboot bootloader installer for installation in SUBDIR, 685 "Make a bootloader-installer for a grub-efi-netboot bootloader, which expects
679which is usually efi/Guix or efi/boot." 686its files in SUBDIR and its configuration file in GRUB-CFG.
680 (let* ((system (string-split (nix-system->gnu-triplet 687
681 (or (%current-target-system) 688As a grub-efi-netboot package is already pre-installed by 'grub-mknetdir', the
682 (%current-system))) 689installer basically copies all files from the bootloader-package (or profile)
683 #\-)) 690into the bootloader-target directory.
684 (arch (first system)) 691
685 (boot-efi-link (match system 692Additionally for network booting over TFTP, two relative symlinks to the store
686 ;; These are the supportend systems and the names 693and to the GRUB-CFG file are necessary. Due to this a TFTP root directory must
687 ;; defined by the UEFI standard for removable media. 694not be located on a FAT file-system.
688 (("i686" _ ...) "/bootia32.efi") 695
689 (("x86_64" _ ...) "/bootx64.efi") 696If the bootloader-target does not support symlinks, then it is assumed to be a
690 (("arm" _ ...) "/bootarm.efi") 697kind of EFI System Partition (ESP). In this case an intermediate configuration
691 (("aarch64" _ ...) "/bootaa64.efi") 698file is created with the help of GRUB-EFI to load the GRUB-CFG.
692 (("riscv" _ ...) "/bootriscv32.efi") 699
693 (("riscv64" _ ...) "/bootriscv64.efi") 700The installer is usable for any efi-bootloader-chain, which prepares the
694 ;; Other systems are not supported, although defined. 701bootloader-profile in a way ready for copying.
695 ;; (("riscv128" _ ...) "/bootriscv128.efi") 702
696 ;; (("ia64" _ ...) "/bootia64.efi") 703The installer does not manipulate the system's 'UEFI Boot Manager'.
697 ((_ ...) #f))) 704
698 (core-efi (string-append 705The returned installer accepts the BOOTLOADER, TARGET and MOUNT-POINT
699 ;; This is the arch dependent file name of GRUB, e.g. 706arguments. Its job is to copy the BOOTLOADER, which must be a pre-installed
700 ;; i368-efi/core.efi or arm64-efi/core.efi. 707grub-efi-netboot package with a SUBDIR like efi/boot or efi/Guix, below the
701 (match arch 708directory TARGET for the system whose root is mounted at MOUNT-POINT.
702 ("i686" "i386")
703 ("aarch64" "arm64")
704 ("riscv" "riscv32")
705 (_ arch))
706 "-efi/core.efi")))
707 (with-imported-modules
708 '((guix build union))
709 #~(lambda (bootloader target mount-point)
710 "Install the BOOTLOADER, which must be the package grub, as e.g.
711bootx64.efi or bootaa64.efi into SUBDIR, which is usually efi/Guix or efi/boot,
712below the directory TARGET for the system whose root is mounted at MOUNT-POINT.
713 709
714MOUNT-POINT is the last argument in 'guix system init /etc/config.scm mnt/point' 710MOUNT-POINT is the last argument in 'guix system init /etc/config.scm mnt/point'
715or '/' for other 'guix system' commands. 711or '/' for other 'guix system' commands.
@@ -719,17 +715,19 @@ bootloader-configuration in:
719 715
720(operating-system 716(operating-system
721 (bootloader (bootloader-configuration 717 (bootloader (bootloader-configuration
722 (targets '(\"/boot\")) 718 (targets '(\"/boot/efi\"))
723 …)) 719 …))
724 …) 720 …)
725 721
726TARGET is required to be an absolute directory name, usually mounted via NFS, 722TARGET is required to be an absolute directory name, usually mounted via NFS,
727and finally needs to be provided by a TFTP server as the TFTP root directory. 723and finally needs to be provided by a TFTP server as
724the TFTP root directory.
728 725
726Usually the installer will be used to prepare network booting over TFTP. Then
729GRUB will load tftp://server/SUBDIR/grub.cfg and this file will instruct it to 727GRUB will load tftp://server/SUBDIR/grub.cfg and this file will instruct it to
730load more files from the store like tftp://server/gnu/store/…-linux…/Image. 728load more files from the store like tftp://server/gnu/store/…-linux…/Image.
731 729
732To make this possible two symlinks will be created. The first symlink points 730To make this possible two symlinks are created. The first symlink points
733relatively form MOUNT-POINT/TARGET/SUBDIR/grub.cfg to 731relatively form MOUNT-POINT/TARGET/SUBDIR/grub.cfg to
734MOUNT-POINT/boot/grub/grub.cfg, and the second symlink points relatively from 732MOUNT-POINT/boot/grub/grub.cfg, and the second symlink points relatively from
735MOUNT-POINT/TARGET/%store-prefix to MOUNT-POINT/%store-prefix. 733MOUNT-POINT/TARGET/%store-prefix to MOUNT-POINT/%store-prefix.
@@ -739,34 +737,80 @@ paths on the TFTP server side are unknown.
739 737
740It is also important to note that both symlinks will point outside the TFTP root 738It is also important to note that both symlinks will point outside the TFTP root
741directory and that the TARGET/%store-prefix symlink makes the whole store 739directory and that the TARGET/%store-prefix symlink makes the whole store
742accessible via TFTP. Possibly the TFTP server must be configured 740accessible via TFTP. Possibly the TFTP server must be configured to allow
743to allow accesses outside its TFTP root directory. This may need to be 741accesses outside its TFTP root directory. This all may need to be considered
744considered for security aspects." 742for security aspects. It is advised to disable any TFTP write access!
745 (use-modules ((guix build union) #:select (symlink-relative))) 743
746 (let* ((net-dir (string-append mount-point target "/")) 744The installer can also be used to prepare booting from local storage, if the
747 (sub-dir (string-append net-dir #$subdir "/")) 745underlying file-system, like FAT on an EFI System Partition (ESP), does not
748 (store (string-append mount-point (%store-prefix))) 746support symlinks. In this case the MOUNT-POINT/TARGET/SUBDIR/grub.cfg will be
749 (store-link (string-append net-dir (%store-prefix))) 747created with the help of GRUB-EFI to load the /boot/grub/grub.cfg file. A
750 (grub-cfg (string-append mount-point "/boot/grub/grub.cfg")) 748symlink to the store is not needed in this case."
751 (grub-cfg-link (string-append sub-dir (basename grub-cfg))) 749 (with-imported-modules '((guix build union))
752 (boot-efi-link (string-append sub-dir #$boot-efi-link))) 750 #~(lambda (bootloader target mount-point)
753 ;; Prepare the symlink to the store. 751 ;; In context of a disk image creation TARGET will be #f and an
754 (mkdir-p (dirname store-link)) 752 ;; installer is expected to do necessary installations on MOUNT-POINT,
755 (false-if-exception (delete-file store-link)) 753 ;; which will become the root file system. If TARGET is #f, this
756 (symlink-relative store store-link) 754 ;; installer has nothing to do, as it only cares about the EFI System
757 ;; Prepare the symlink to the grub.cfg, which points into the store. 755 ;; Partition (ESP).
758 (mkdir-p (dirname grub-cfg-link)) 756 (when target
759 (false-if-exception (delete-file grub-cfg-link)) 757 (use-modules ((guix build union) #:select (symlink-relative))
760 (symlink-relative grub-cfg grub-cfg-link) 758 (ice-9 popen)
761 ;; Install GRUB, which refers to the grub.cfg, with support for 759 (ice-9 rdelim))
762 ;; encrypted partitions, 760 (let* ((mount-point/target (string-append mount-point target "/"))
763 (setenv "GRUB_ENABLE_CRYPTODISK" "y") 761 ;; When installing Guix, it is common to mount TARGET below
764 (invoke/quiet (string-append bootloader "/bin/grub-mknetdir") 762 ;; MOUNT-POINT rather than the root directory.
765 (string-append "--net-directory=" net-dir) 763 (bootloader-target (if (file-exists? mount-point/target)
766 (string-append "--subdir=" #$subdir)) 764 mount-point/target
767 ;; Prepare the bootloader symlink, which points to core.efi of GRUB. 765 target))
768 (false-if-exception (delete-file boot-efi-link)) 766 (store (string-append mount-point (%store-prefix)))
769 (symlink #$core-efi boot-efi-link)))))) 767 (store-link (string-append bootloader-target (%store-prefix)))
768 (grub-cfg (string-append mount-point #$grub-cfg))
769 (grub-cfg-link (string-append bootloader-target
770 #$subdir "/"
771 (basename grub-cfg))))
772 ;; Copy the bootloader into the bootloader-target directory.
773 ;; Should we beforehand recursively delete any existing file?
774 (copy-recursively bootloader bootloader-target
775 #:follow-symlinks? #t
776 #:log (%make-void-port "w"))
777 ;; For TFTP we need to install additional relative symlinks.
778 ;; If we install on an EFI System Partition (ESP) or some other FAT
779 ;; file-system, then symlinks cannot be created and are not needed.
780 ;; Therefore we ignore exceptions when trying.
781 ;; Prepare the symlink to the grub.cfg.
782 (mkdir-p (dirname grub-cfg-link))
783 (false-if-exception (delete-file grub-cfg-link))
784 (if (unspecified?
785 (false-if-exception (symlink-relative grub-cfg grub-cfg-link)))
786 ;; Symlinks are supported.
787 (begin
788 ;; Prepare the symlink to the store.
789 (mkdir-p (dirname store-link))
790 (false-if-exception (delete-file store-link))
791 (symlink-relative store store-link))
792 ;; Creating symlinks does not seem to be supported. Probably
793 ;; an ESP is used. Add a script to search and load the actual
794 ;; grub.cfg.
795 (let* ((probe #$(file-append grub-efi "/sbin/grub-probe"))
796 (port (open-pipe* OPEN_READ probe "--target=fs_uuid"
797 grub-cfg))
798 (search-root
799 (match (read-line port)
800 ((? eof-object?)
801 ;; There is no UUID available. As a fallback search
802 ;; everywhere for the grub.cfg.
803 (string-append "search --file --set " #$grub-cfg))
804 (fs-uuid
805 ;; The UUID to load the grub.cfg from is known.
806 (string-append "search --fs-uuid --set " fs-uuid))))
807 (load-grub-cfg (string-append "configfile " #$grub-cfg)))
808 (close-pipe port)
809 (with-output-to-file grub-cfg-link
810 (lambda ()
811 (display (string-join (list search-root
812 load-grub-cfg)
813 "\n")))))))))))
770 814
771 815
772 816
@@ -784,7 +828,7 @@ considered for security aspects."
784 (package grub) 828 (package grub)
785 (installer install-grub) 829 (installer install-grub)
786 (disk-image-installer install-grub-disk-image) 830 (disk-image-installer install-grub-disk-image)
787 (configuration-file "/boot/grub/grub.cfg") 831 (configuration-file grub-cfg)
788 (configuration-file-generator grub-configuration-file))) 832 (configuration-file-generator grub-configuration-file)))
789 833
790(define grub-minimal-bootloader 834(define grub-minimal-bootloader
@@ -794,11 +838,12 @@ considered for security aspects."
794 838
795(define grub-efi-bootloader 839(define grub-efi-bootloader
796 (bootloader 840 (bootloader
797 (inherit grub-bootloader) 841 (name 'grub-efi)
842 (package grub-efi)
798 (installer install-grub-efi) 843 (installer install-grub-efi)
799 (disk-image-installer #f) 844 (disk-image-installer #f)
800 (name 'grub-efi) 845 (configuration-file grub-cfg)
801 (package grub-efi))) 846 (configuration-file-generator grub-configuration-file)))
802 847
803(define grub-efi-removable-bootloader 848(define grub-efi-removable-bootloader
804 (bootloader 849 (bootloader
@@ -813,11 +858,22 @@ considered for security aspects."
813 (name 'grub-efi32) 858 (name 'grub-efi32)
814 (package grub-efi32))) 859 (package grub-efi32)))
815 860
816(define grub-efi-netboot-bootloader 861(define (make-grub-efi-netboot-bootloader name subdir)
817 (bootloader 862 (bootloader
818 (inherit grub-efi-bootloader) 863 (name name)
819 (name 'grub-efi-netboot-bootloader) 864 (package (make-grub-efi-netboot (symbol->string name) subdir))
820 (installer (install-grub-efi-netboot "efi/Guix")))) 865 (installer (make-grub-efi-netboot-installer grub-efi grub-cfg subdir))
866 (disk-image-installer #f)
867 (configuration-file grub-cfg)
868 (configuration-file-generator grub-efi-configuration-file)))
869
870(define grub-efi-netboot-bootloader
871 (make-grub-efi-netboot-bootloader 'grub-efi-netboot-bootloader
872 "efi/Guix"))
873
874(define grub-efi-netboot-removable-bootloader
875 (make-grub-efi-netboot-bootloader 'grub-efi-netboot-removable-bootloader
876 "efi/boot"))
821 877
822(define grub-mkrescue-bootloader 878(define grub-mkrescue-bootloader
823 (bootloader 879 (bootloader