diff options
| author | Mathieu Othacehe <m.othacehe@gmail.com> | 2017-05-15 22:24:18 +0200 |
|---|---|---|
| committer | Mathieu Othacehe <m.othacehe@gmail.com> | 2017-05-16 14:41:01 +0200 |
| commit | b09a8da4a2e50845a297e041762f3ff9e649c047 (patch) | |
| tree | 41111b45d2af2ec06c0a7262f390bfd5e91639c1 /gnu/bootloader | |
| parent | ce92d269fea0a2bfac0ac20414f77127d2f07500 (diff) | |
bootloader: Add extlinux support.
* gnu/bootloader.scm: New file.
* gnu/bootloader/extlinux.scm: New file.
* gnu/bootloader/grub.scm: New file.
* gnu/local.mk: Build new files.
* gnu/system.scm: Adapt to new bootloader api.
* gnu/scripts/system.scm: Adapt to new bootloader api.
* gnu.scm: Remove (gnu system grub) and replace by (gnu bootloader) and (gnu
bootloader grub) modules.
* gnu/system/grub.scm: Moved content to gnu/bootloader/grub.scm.
* gnu/system/vm: Replace (gnu system grub) module by (gnu bootloader).
* gnu/tests.scm: Ditto.
* gnu/tests/nfs.scm: Ditto.
Diffstat (limited to 'gnu/bootloader')
| -rw-r--r-- | gnu/bootloader/extlinux.scm | 123 | ||||
| -rw-r--r-- | gnu/bootloader/grub.scm | 448 |
2 files changed, 571 insertions, 0 deletions
diff --git a/gnu/bootloader/extlinux.scm b/gnu/bootloader/extlinux.scm new file mode 100644 index 00000000000..a0020010718 --- /dev/null +++ b/gnu/bootloader/extlinux.scm | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | ;;; GNU Guix --- Functional package management for GNU | ||
| 2 | ;;; Copyright © 2017 David Craven <david@craven.ch> | ||
| 3 | ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> | ||
| 4 | ;;; | ||
| 5 | ;;; This file is part of GNU Guix. | ||
| 6 | ;;; | ||
| 7 | ;;; GNU Guix is free software; you can redistribute it and/or modify it | ||
| 8 | ;;; under the terms of the GNU General Public License as published by | ||
| 9 | ;;; the Free Software Foundation; either version 3 of the License, or (at | ||
| 10 | ;;; your option) any later version. | ||
| 11 | ;;; | ||
| 12 | ;;; GNU Guix is distributed in the hope that it will be useful, but | ||
| 13 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | ;;; GNU General Public License for more details. | ||
| 16 | ;;; | ||
| 17 | ;;; You should have received a copy of the GNU General Public License | ||
| 18 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | ||
| 19 | |||
| 20 | (define-module (gnu bootloader extlinux) | ||
| 21 | #:use-module (gnu bootloader) | ||
| 22 | #:use-module (gnu system) | ||
| 23 | #:use-module (gnu packages bootloaders) | ||
| 24 | #:use-module (guix gexp) | ||
| 25 | #:use-module (guix monads) | ||
| 26 | #:use-module (guix records) | ||
| 27 | #:use-module (guix utils) | ||
| 28 | #:export (extlinux-bootloader | ||
| 29 | syslinux-bootloader | ||
| 30 | |||
| 31 | extlinux-configuration | ||
| 32 | syslinux-configuration)) | ||
| 33 | |||
| 34 | (define* (extlinux-configuration-file config entries | ||
| 35 | #:key | ||
| 36 | (system (%current-system)) | ||
| 37 | (old-entries '())) | ||
| 38 | "Return the U-Boot configuration file corresponding to CONFIG, a | ||
| 39 | <u-boot-configuration> object, and where the store is available at STORE-FS, a | ||
| 40 | <file-system> object. OLD-ENTRIES is taken to be a list of menu entries | ||
| 41 | corresponding to old generations of the system." | ||
| 42 | |||
| 43 | (define all-entries | ||
| 44 | (append entries (bootloader-configuration-menu-entries config))) | ||
| 45 | |||
| 46 | (define (boot-parameters->gexp params) | ||
| 47 | (let ((label (boot-parameters-label params)) | ||
| 48 | (kernel (boot-parameters-kernel params)) | ||
| 49 | (kernel-arguments (boot-parameters-kernel-arguments params)) | ||
| 50 | (initrd (boot-parameters-initrd params))) | ||
| 51 | #~(format port "LABEL ~a | ||
| 52 | MENU LABEL ~a | ||
| 53 | KERNEL ~a | ||
| 54 | FDTDIR ~a/lib/dtbs | ||
| 55 | INITRD ~a | ||
| 56 | APPEND ~a | ||
| 57 | ~%" | ||
| 58 | #$label #$label | ||
| 59 | #$kernel #$kernel #$initrd | ||
| 60 | (string-join (list #$@kernel-arguments))))) | ||
| 61 | |||
| 62 | (define builder | ||
| 63 | #~(call-with-output-file #$output | ||
| 64 | (lambda (port) | ||
| 65 | (let ((timeout #$(bootloader-configuration-timeout config))) | ||
| 66 | (format port " | ||
| 67 | UI menu.c32 | ||
| 68 | PROMPT ~a | ||
| 69 | TIMEOUT ~a~%" | ||
| 70 | (if (> timeout 0) 1 0) | ||
| 71 | ;; timeout is expressed in 1/10s of seconds. | ||
| 72 | (* 10 timeout)) | ||
| 73 | #$@(map boot-parameters->gexp all-entries) | ||
| 74 | |||
| 75 | #$@(if (pair? old-entries) | ||
| 76 | #~((format port "~%") | ||
| 77 | #$@(map boot-parameters->gexp old-entries) | ||
| 78 | (format port "~%")) | ||
| 79 | #~()))))) | ||
| 80 | |||
| 81 | (gexp->derivation "extlinux.conf" builder)) | ||
| 82 | |||
| 83 | |||
| 84 | |||
| 85 | |||
| 86 | ;;; | ||
| 87 | ;;; Install procedures. | ||
| 88 | ;;; | ||
| 89 | |||
| 90 | (define dd | ||
| 91 | #~(lambda (bs count if of) | ||
| 92 | (zero? (system* "dd" | ||
| 93 | (string-append "bs=" (number->string bs)) | ||
| 94 | (string-append "count=" (number->string count)) | ||
| 95 | (string-append "if=" if) | ||
| 96 | (string-append "of=" of))))) | ||
| 97 | |||
| 98 | (define install-extlinux | ||
| 99 | #~(lambda (bootloader device mount-point) | ||
| 100 | (let ((extlinux (string-append bootloader "/sbin/extlinux")) | ||
| 101 | (install-dir (string-append mount-point "/boot/extlinux")) | ||
| 102 | (syslinux-dir (string-append bootloader "/share/syslinux"))) | ||
| 103 | (for-each (lambda (file) | ||
| 104 | (install-file file install-dir)) | ||
| 105 | (find-files syslinux-dir "\\.c32$")) | ||
| 106 | |||
| 107 | (unless (and (zero? (system* extlinux "--install" install-dir)) | ||
| 108 | (#$dd 440 1 (string-append syslinux-dir "/mbr.bin") device)) | ||
| 109 | (error "failed to install SYSLINUX"))))) | ||
| 110 | |||
| 111 | |||
| 112 | |||
| 113 | ;;; | ||
| 114 | ;;; Bootloader definitions. | ||
| 115 | ;;; | ||
| 116 | |||
| 117 | (define extlinux-bootloader | ||
| 118 | (bootloader | ||
| 119 | (name 'extlinux) | ||
| 120 | (package syslinux) | ||
| 121 | (installer install-extlinux) | ||
| 122 | (configuration-file "/boot/extlinux/extlinux.conf") | ||
| 123 | (configuration-file-generator extlinux-configuration-file))) | ||
diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scm new file mode 100644 index 00000000000..49616b71642 --- /dev/null +++ b/gnu/bootloader/grub.scm | |||
| @@ -0,0 +1,448 @@ | |||
| 1 | ;;; GNU Guix --- Functional package management for GNU | ||
| 2 | ;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org> | ||
| 3 | ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com> | ||
| 4 | ;;; Copyright © 2017 Leo Famulari <leo@famulari.name> | ||
| 5 | ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> | ||
| 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 bootloader grub) | ||
| 23 | #:use-module (guix store) | ||
| 24 | #:use-module (guix packages) | ||
| 25 | #:use-module (guix derivations) | ||
| 26 | #:use-module (guix records) | ||
| 27 | #:use-module (guix monads) | ||
| 28 | #:use-module (guix gexp) | ||
| 29 | #:use-module (guix download) | ||
| 30 | #:use-module (gnu artwork) | ||
| 31 | #:use-module (gnu system) | ||
| 32 | #:use-module (gnu bootloader) | ||
| 33 | #:use-module (gnu system file-systems) | ||
| 34 | #:autoload (gnu packages bootloaders) (grub) | ||
| 35 | #:autoload (gnu packages compression) (gzip) | ||
| 36 | #:autoload (gnu packages gtk) (guile-cairo guile-rsvg) | ||
| 37 | #:use-module (ice-9 match) | ||
| 38 | #:use-module (ice-9 regex) | ||
| 39 | #:use-module (srfi srfi-1) | ||
| 40 | #:use-module (rnrs bytevectors) | ||
| 41 | #:export (grub-image | ||
| 42 | grub-image? | ||
| 43 | grub-image-aspect-ratio | ||
| 44 | grub-image-file | ||
| 45 | |||
| 46 | grub-theme | ||
| 47 | grub-theme? | ||
| 48 | grub-theme-images | ||
| 49 | grub-theme-color-normal | ||
| 50 | grub-theme-color-highlight | ||
| 51 | |||
| 52 | %background-image | ||
| 53 | %default-theme | ||
| 54 | |||
| 55 | grub-bootloader | ||
| 56 | grub-efi-bootloader | ||
| 57 | |||
| 58 | grub-configuration)) | ||
| 59 | |||
| 60 | ;;; Commentary: | ||
| 61 | ;;; | ||
| 62 | ;;; Configuration of GNU GRUB. | ||
| 63 | ;;; | ||
| 64 | ;;; Code: | ||
| 65 | |||
| 66 | (define (strip-mount-point mount-point file) | ||
| 67 | "Strip MOUNT-POINT from FILE, which is a gexp or other lowerable object | ||
| 68 | denoting a file name." | ||
| 69 | (if (string=? mount-point "/") | ||
| 70 | file | ||
| 71 | #~(let ((file #$file)) | ||
| 72 | (if (string-prefix? #$mount-point file) | ||
| 73 | (substring #$file #$(string-length mount-point)) | ||
| 74 | file)))) | ||
| 75 | |||
| 76 | (define-record-type* <grub-image> | ||
| 77 | grub-image make-grub-image | ||
| 78 | grub-image? | ||
| 79 | (aspect-ratio grub-image-aspect-ratio ;rational number | ||
| 80 | (default 4/3)) | ||
| 81 | (file grub-image-file)) ;file-valued gexp (SVG) | ||
| 82 | |||
| 83 | (define-record-type* <grub-theme> | ||
| 84 | grub-theme make-grub-theme | ||
| 85 | grub-theme? | ||
| 86 | (images grub-theme-images | ||
| 87 | (default '())) ;list of <grub-image> | ||
| 88 | (color-normal grub-theme-color-normal | ||
| 89 | (default '((fg . cyan) (bg . blue)))) | ||
| 90 | (color-highlight grub-theme-color-highlight | ||
| 91 | (default '((fg . white) (bg . blue))))) | ||
| 92 | |||
| 93 | (define %background-image | ||
| 94 | (grub-image | ||
| 95 | (aspect-ratio 4/3) | ||
| 96 | (file (file-append %artwork-repository | ||
| 97 | "/grub/GuixSD-fully-black-4-3.svg")))) | ||
| 98 | |||
| 99 | (define %default-theme | ||
| 100 | ;; Default theme contributed by Felipe López. | ||
| 101 | (grub-theme | ||
| 102 | (images (list %background-image)) | ||
| 103 | (color-highlight '((fg . yellow) (bg . black))) | ||
| 104 | (color-normal '((fg . light-gray) (bg . black))))) ;XXX: #x303030 | ||
| 105 | |||
| 106 | (define-record-type* <menu-entry> | ||
| 107 | menu-entry make-menu-entry | ||
| 108 | menu-entry? | ||
| 109 | (label menu-entry-label) | ||
| 110 | (device menu-entry-device ; file system uuid, label, or #f | ||
| 111 | (default #f)) | ||
| 112 | (device-mount-point menu-entry-device-mount-point | ||
| 113 | (default "/")) | ||
| 114 | (linux menu-entry-linux) | ||
| 115 | (linux-arguments menu-entry-linux-arguments | ||
| 116 | (default '())) ; list of string-valued gexps | ||
| 117 | (initrd menu-entry-initrd)) ; file name of the initrd as a gexp | ||
| 118 | |||
| 119 | |||
| 120 | ;;; | ||
| 121 | ;;; Background image & themes. | ||
| 122 | ;;; | ||
| 123 | |||
| 124 | (define (bootloader-theme config) | ||
| 125 | "Return user defined theme in CONFIG if defined or %default-theme | ||
| 126 | otherwise." | ||
| 127 | (or (bootloader-configuration-theme config) %default-theme)) | ||
| 128 | |||
| 129 | (define* (svg->png svg #:key width height) | ||
| 130 | "Build a PNG of HEIGHT x WIDTH from SVG." | ||
| 131 | (gexp->derivation "grub-image.png" | ||
| 132 | (with-imported-modules '((gnu build svg)) | ||
| 133 | #~(begin | ||
| 134 | ;; We need these two libraries. | ||
| 135 | (add-to-load-path (string-append #+guile-rsvg | ||
| 136 | "/share/guile/site/" | ||
| 137 | (effective-version))) | ||
| 138 | (add-to-load-path (string-append #+guile-cairo | ||
| 139 | "/share/guile/site/" | ||
| 140 | (effective-version))) | ||
| 141 | |||
| 142 | (use-modules (gnu build svg)) | ||
| 143 | (svg->png #+svg #$output | ||
| 144 | #:width #$width | ||
| 145 | #:height #$height))))) | ||
| 146 | |||
| 147 | (define* (grub-background-image config #:key (width 1024) (height 768)) | ||
| 148 | "Return the GRUB background image defined in CONFIG with a ratio of | ||
| 149 | WIDTH/HEIGHT, or #f if none was found." | ||
| 150 | (let* ((ratio (/ width height)) | ||
| 151 | (image (find (lambda (image) | ||
| 152 | (= (grub-image-aspect-ratio image) ratio)) | ||
| 153 | (grub-theme-images | ||
| 154 | (bootloader-theme config))))) | ||
| 155 | (if image | ||
| 156 | (svg->png (grub-image-file image) | ||
| 157 | #:width width #:height height) | ||
| 158 | (with-monad %store-monad | ||
| 159 | (return #f))))) | ||
| 160 | |||
| 161 | (define* (eye-candy config store-device store-mount-point | ||
| 162 | #:key system port) | ||
| 163 | "Return in %STORE-MONAD a gexp that writes to PORT (a port-valued gexp) the | ||
| 164 | 'grub.cfg' part concerned with graphics mode, background images, colors, and | ||
| 165 | all that. STORE-DEVICE designates the device holding the store, and | ||
| 166 | STORE-MOUNT-POINT is its mount point; these are used to determine where the | ||
| 167 | background image and fonts must be searched for. SYSTEM must be the target | ||
| 168 | system string---e.g., \"x86_64-linux\"." | ||
| 169 | (define setup-gfxterm-body | ||
| 170 | ;; Intel and EFI systems need to be switched into graphics mode, whereas | ||
| 171 | ;; most other modern architectures have no other mode and therefore don't | ||
| 172 | ;; need to be switched. | ||
| 173 | (if (string-match "^(x86_64|i[3-6]86)-" system) | ||
| 174 | " | ||
| 175 | # Leave 'gfxmode' to 'auto'. | ||
| 176 | insmod video_bochs | ||
| 177 | insmod video_cirrus | ||
| 178 | insmod gfxterm | ||
| 179 | |||
| 180 | if [ \"${grub_platform}\" == efi ]; then | ||
| 181 | # This is for (U)EFI systems (these modules are unavailable in the | ||
| 182 | # non-EFI GRUB.) If we don't load them, GRUB boots in \"blind mode\", | ||
| 183 | # which isn't convenient. | ||
| 184 | insmod efi_gop | ||
| 185 | insmod efi_uga | ||
| 186 | else | ||
| 187 | # These are specific to non-EFI Intel machines. | ||
| 188 | insmod vbe | ||
| 189 | insmod vga | ||
| 190 | fi | ||
| 191 | " | ||
| 192 | "")) | ||
| 193 | |||
| 194 | (define (setup-gfxterm config font-file) | ||
| 195 | (if (memq 'gfxterm (bootloader-configuration-terminal-outputs config)) | ||
| 196 | #~(format #f "if loadfont ~a; then | ||
| 197 | setup_gfxterm | ||
| 198 | fi~%" #$font-file) | ||
| 199 | "")) | ||
| 200 | |||
| 201 | (define (theme-colors type) | ||
| 202 | (let* ((theme (bootloader-theme config)) | ||
| 203 | (colors (type theme))) | ||
| 204 | (string-append (symbol->string (assoc-ref colors 'fg)) "/" | ||
| 205 | (symbol->string (assoc-ref colors 'bg))))) | ||
| 206 | |||
| 207 | (define font-file | ||
| 208 | (strip-mount-point store-mount-point | ||
| 209 | (file-append grub "/share/grub/unicode.pf2"))) | ||
| 210 | |||
| 211 | (mlet* %store-monad ((image (grub-background-image config))) | ||
| 212 | (return (and image | ||
| 213 | #~(format #$port " | ||
| 214 | function setup_gfxterm {~a} | ||
| 215 | |||
| 216 | # Set 'root' to the partition that contains /gnu/store. | ||
| 217 | ~a | ||
| 218 | |||
| 219 | ~a | ||
| 220 | ~a | ||
| 221 | |||
| 222 | insmod png | ||
| 223 | if background_image ~a; then | ||
| 224 | set color_normal=~a | ||
| 225 | set color_highlight=~a | ||
| 226 | else | ||
| 227 | set menu_color_normal=cyan/blue | ||
| 228 | set menu_color_highlight=white/blue | ||
| 229 | fi~%" | ||
| 230 | #$setup-gfxterm-body | ||
| 231 | #$(grub-root-search store-device font-file) | ||
| 232 | #$(setup-gfxterm config font-file) | ||
| 233 | #$(grub-setup-io config) | ||
| 234 | |||
| 235 | #$(strip-mount-point store-mount-point image) | ||
| 236 | #$(theme-colors grub-theme-color-normal) | ||
| 237 | #$(theme-colors grub-theme-color-highlight)))))) | ||
| 238 | |||
| 239 | |||
| 240 | ;;; | ||
| 241 | ;;; Configuration file. | ||
| 242 | ;;; | ||
| 243 | |||
| 244 | (define (grub-setup-io config) | ||
| 245 | "Return GRUB commands to configure the input / output interfaces. The result | ||
| 246 | is a string that can be inserted in grub.cfg." | ||
| 247 | (let* ((symbols->string (lambda (list) | ||
| 248 | (string-join (map symbol->string list) " "))) | ||
| 249 | (outputs (bootloader-configuration-terminal-outputs config)) | ||
| 250 | (inputs (bootloader-configuration-terminal-inputs config)) | ||
| 251 | (unit (bootloader-configuration-serial-unit config)) | ||
| 252 | (speed (bootloader-configuration-serial-speed config)) | ||
| 253 | |||
| 254 | ;; Respectively, GRUB_TERMINAL_OUTPUT and GRUB_TERMINAL_INPUT, | ||
| 255 | ;; as documented in GRUB manual section "Simple Configuration | ||
| 256 | ;; Handling". | ||
| 257 | (valid-outputs '(console serial serial_0 serial_1 serial_2 serial_3 | ||
| 258 | gfxterm vga_text mda_text morse spkmodem)) | ||
| 259 | (valid-inputs '(console serial serial_0 serial_1 serial_2 serial_3 | ||
| 260 | at_keyboard usb_keyboard)) | ||
| 261 | |||
| 262 | (io (string-append | ||
| 263 | "terminal_output " | ||
| 264 | (symbols->string | ||
| 265 | (map | ||
| 266 | (lambda (output) | ||
| 267 | (if (memq output valid-outputs) output #f)) outputs)) "\n" | ||
| 268 | (if (null? inputs) | ||
| 269 | "" | ||
| 270 | (string-append | ||
| 271 | "terminal_input " | ||
| 272 | (symbols->string | ||
| 273 | (map | ||
| 274 | (lambda (input) | ||
| 275 | (if (memq input valid-inputs) input #f)) inputs)) "\n")) | ||
| 276 | ;; UNIT and SPEED are arguments to the same GRUB command | ||
| 277 | ;; ("serial"), so we process them together. | ||
| 278 | (if (or unit speed) | ||
| 279 | (string-append | ||
| 280 | "serial" | ||
| 281 | (if unit | ||
| 282 | ;; COM ports 1 through 4 | ||
| 283 | (if (and (exact-integer? unit) (<= unit 3) (>= unit 0)) | ||
| 284 | (string-append " --unit=" (number->string unit)) | ||
| 285 | #f) | ||
| 286 | "") | ||
| 287 | (if speed | ||
| 288 | (if (exact-integer? speed) | ||
| 289 | (string-append " --speed=" (number->string speed)) | ||
| 290 | #f) | ||
| 291 | "")) | ||
| 292 | "")))) | ||
| 293 | (format #f "~a" io))) | ||
| 294 | |||
| 295 | (define (grub-root-search device file) | ||
| 296 | "Return the GRUB 'search' command to look for DEVICE, which contains FILE, | ||
| 297 | a gexp. The result is a gexp that can be inserted in the grub.cfg-generation | ||
| 298 | code." | ||
| 299 | ;; Usually FILE is a file name gexp like "/gnu/store/…-linux/vmlinuz", but | ||
| 300 | ;; it can also be something like "(hd0,msdos1)/vmlinuz" in the case of | ||
| 301 | ;; custom menu entries. In the latter case, don't emit a 'search' command. | ||
| 302 | (if (and (string? file) (not (string-prefix? "/" file))) | ||
| 303 | "" | ||
| 304 | (match device | ||
| 305 | ;; Preferably refer to DEVICE by its UUID or label. This is more | ||
| 306 | ;; efficient and less ambiguous, see <http://bugs.gnu.org/22281>. | ||
| 307 | ((? bytevector? uuid) | ||
| 308 | (format #f "search --fs-uuid --set ~a" | ||
| 309 | (uuid->string device))) | ||
| 310 | ((? string? label) | ||
| 311 | (format #f "search --label --set ~a" label)) | ||
| 312 | (#f | ||
| 313 | #~(format #f "search --file --set ~a" #$file))))) | ||
| 314 | |||
| 315 | (define (boot-parameters->menu-entry conf) | ||
| 316 | "Convert a <boot-parameters> instance to a corresponding <menu-entry>." | ||
| 317 | (menu-entry | ||
| 318 | (label (boot-parameters-label conf)) | ||
| 319 | (device (boot-parameters-store-device conf)) | ||
| 320 | (device-mount-point (boot-parameters-store-mount-point conf)) | ||
| 321 | (linux (boot-parameters-kernel conf)) | ||
| 322 | (linux-arguments (boot-parameters-kernel-arguments conf)) | ||
| 323 | (initrd (boot-parameters-initrd conf)))) | ||
| 324 | |||
| 325 | (define* (grub-configuration-file config entries | ||
| 326 | #:key | ||
| 327 | (system (%current-system)) | ||
| 328 | (old-entries '())) | ||
| 329 | "Return the GRUB configuration file corresponding to CONFIG, a | ||
| 330 | <bootloader-configuration> object, and where the store is available at | ||
| 331 | STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu | ||
| 332 | entries corresponding to old generations of the system." | ||
| 333 | (define all-entries | ||
| 334 | (map boot-parameters->menu-entry | ||
| 335 | (append entries | ||
| 336 | (bootloader-configuration-menu-entries config)))) | ||
| 337 | |||
| 338 | (define entry->gexp | ||
| 339 | (match-lambda | ||
| 340 | (($ <menu-entry> label device device-mount-point | ||
| 341 | linux arguments initrd) | ||
| 342 | ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point. | ||
| 343 | ;; Use the right file names for LINUX and INITRD in case | ||
| 344 | ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a | ||
| 345 | ;; separate partition. | ||
| 346 | (let ((linux (strip-mount-point device-mount-point linux)) | ||
| 347 | (initrd (strip-mount-point device-mount-point initrd))) | ||
| 348 | #~(format port "menuentry ~s { | ||
| 349 | ~a | ||
| 350 | linux ~a ~a | ||
| 351 | initrd ~a | ||
| 352 | }~%" | ||
| 353 | #$label | ||
| 354 | #$(grub-root-search device linux) | ||
| 355 | #$linux (string-join (list #$@arguments)) | ||
| 356 | #$initrd))))) | ||
| 357 | |||
| 358 | (mlet %store-monad ((sugar (eye-candy config | ||
| 359 | (menu-entry-device (first all-entries)) | ||
| 360 | (menu-entry-device-mount-point | ||
| 361 | (first all-entries)) | ||
| 362 | #:system system | ||
| 363 | #:port #~port))) | ||
| 364 | (define builder | ||
| 365 | #~(call-with-output-file #$output | ||
| 366 | (lambda (port) | ||
| 367 | (format port | ||
| 368 | "# This file was generated from your GuixSD configuration. Any changes | ||
| 369 | # will be lost upon reconfiguration. | ||
| 370 | ") | ||
| 371 | #$sugar | ||
| 372 | (format port " | ||
| 373 | set default=~a | ||
| 374 | set timeout=~a~%" | ||
| 375 | #$(bootloader-configuration-default-entry config) | ||
| 376 | #$(bootloader-configuration-timeout config)) | ||
| 377 | #$@(map entry->gexp all-entries) | ||
| 378 | |||
| 379 | #$@(if (pair? old-entries) | ||
| 380 | #~((format port " | ||
| 381 | submenu \"GNU system, old configurations...\" {~%") | ||
| 382 | #$@(map entry->gexp (map boot-parameters->menu-entry old-entries)) | ||
| 383 | (format port "}~%")) | ||
| 384 | #~())))) | ||
| 385 | |||
| 386 | (gexp->derivation "grub.cfg" builder))) | ||
| 387 | |||
| 388 | |||
| 389 | |||
| 390 | ;;; | ||
| 391 | ;;; Install procedures. | ||
| 392 | ;;; | ||
| 393 | |||
| 394 | (define install-grub | ||
| 395 | #~(lambda (bootloader device mount-point) | ||
| 396 | ;; Install GRUB on DEVICE which is mounted at MOUNT-POINT. | ||
| 397 | (let ((grub (string-append bootloader "/sbin/grub-install")) | ||
| 398 | (install-dir (string-append mount-point "/boot"))) | ||
| 399 | ;; Tell 'grub-install' that there might be a LUKS-encrypted /boot or | ||
| 400 | ;; root partition. | ||
| 401 | (setenv "GRUB_ENABLE_CRYPTODISK" "y") | ||
| 402 | |||
| 403 | (unless (zero? (system* grub "--no-floppy" | ||
| 404 | "--boot-directory" install-dir | ||
| 405 | device)) | ||
| 406 | (error "failed to install GRUB"))))) | ||
| 407 | |||
| 408 | |||
| 409 | |||
| 410 | ;;; | ||
| 411 | ;;; Bootloader definitions. | ||
| 412 | ;;; | ||
| 413 | |||
| 414 | (define grub-bootloader | ||
| 415 | (bootloader | ||
| 416 | (name 'grub) | ||
| 417 | (package grub) | ||
| 418 | (installer install-grub) | ||
| 419 | (configuration-file "/boot/grub/grub.cfg") | ||
| 420 | (configuration-file-generator grub-configuration-file))) | ||
| 421 | |||
| 422 | (define* grub-efi-bootloader | ||
| 423 | (bootloader | ||
| 424 | (inherit grub-bootloader) | ||
| 425 | (name 'grub-efi) | ||
| 426 | (package grub-efi))) | ||
| 427 | |||
| 428 | |||
| 429 | ;;; | ||
| 430 | ;;; Compatibility macros. | ||
| 431 | ;;; | ||
| 432 | |||
| 433 | (define-syntax grub-configuration | ||
| 434 | (syntax-rules (grub) | ||
| 435 | ((_ (grub package) fields ...) | ||
| 436 | (if (eq? package grub) | ||
| 437 | (bootloader-configuration | ||
| 438 | (bootloader grub-bootloader) | ||
| 439 | fields ...) | ||
| 440 | (bootloader-configuration | ||
| 441 | (bootloader grub-efi-bootloader) | ||
| 442 | fields ...))) | ||
| 443 | ((_ fields ...) | ||
| 444 | (bootloader-configuration | ||
| 445 | (bootloader grub-bootloader) | ||
| 446 | fields ...)))) | ||
| 447 | |||
| 448 | ;;; grub.scm ends here | ||
