Commit | Line | Data |
---|---|---|
f09d925b | 1 | ;;; GNU Guix --- Functional package management for GNU |
278d486b | 2 | ;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org> |
cc023e32 | 3 | ;;; Copyright © 2016 Mark H Weaver <mhw@netris.org> |
ad857912 | 4 | ;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org> |
47bdc5a1 | 5 | ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> |
f09d925b LC |
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 | ||
735c6dd7 LC |
22 | (define-module (gnu system linux-initrd) |
23 | #:use-module (guix monads) | |
e87f0591 | 24 | #:use-module (guix store) |
0c21d92b | 25 | #:use-module (guix gexp) |
f09d925b | 26 | #:use-module (guix utils) |
d4254711 LC |
27 | #:use-module ((guix store) |
28 | #:select (%store-prefix)) | |
1c96c1bb LC |
29 | #:use-module ((guix derivations) |
30 | #:select (derivation->output-path)) | |
239c6e27 | 31 | #:use-module (guix modules) |
f09d925b | 32 | #:use-module (gnu packages compression) |
866872aa | 33 | #:use-module (gnu packages disk) |
f09d925b | 34 | #:use-module (gnu packages linux) |
f989fa39 | 35 | #:use-module (gnu packages guile) |
f09d925b LC |
36 | #:use-module ((gnu packages make-bootstrap) |
37 | #:select (%guile-static-stripped)) | |
c5df1839 | 38 | #:use-module (gnu system file-systems) |
060d62a7 | 39 | #:use-module (gnu system mapped-devices) |
1c96c1bb | 40 | #:use-module (ice-9 match) |
217b862f | 41 | #:use-module (ice-9 regex) |
83bcd0b8 | 42 | #:use-module (srfi srfi-1) |
42d10464 | 43 | #:use-module (srfi srfi-26) |
735c6dd7 | 44 | #:export (expression->initrd |
47bdc5a1 | 45 | raw-initrd |
278d486b | 46 | file-system-packages |
060238ae | 47 | base-initrd)) |
f09d925b LC |
48 | |
49 | \f | |
50 | ;;; Commentary: | |
51 | ;;; | |
52 | ;;; Tools to build initial RAM disks (initrd's) for Linux-Libre, and in | |
53 | ;;; particular initrd's that run Guile. | |
54 | ;;; | |
55 | ;;; Code: | |
56 | ||
57 | ||
58 | (define* (expression->initrd exp | |
59 | #:key | |
60 | (guile %guile-static-stripped) | |
f09d925b LC |
61 | (gzip gzip) |
62 | (name "guile-initrd") | |
4ee96a79 | 63 | (system (%current-system))) |
fd1b1fa2 | 64 | "Return a derivation that builds a Linux initrd (a gzipped cpio archive) |
df650fa8 | 65 | containing GUILE and that evaluates EXP, a G-expression, upon booting. All |
4ee96a79 | 66 | the derivations referenced by EXP are automatically copied to the initrd." |
f09d925b LC |
67 | |
68 | ;; General Linux overview in `Documentation/early-userspace/README' and | |
69 | ;; `Documentation/filesystems/ramfs-rootfs-initramfs.txt'. | |
70 | ||
42d10464 | 71 | (mlet %store-monad ((init (gexp->script "init" exp |
42d10464 | 72 | #:guile guile))) |
0c21d92b | 73 | (define builder |
239c6e27 LC |
74 | (with-imported-modules (source-module-closure |
75 | '((gnu build linux-initrd))) | |
4ee96a79 LC |
76 | #~(begin |
77 | (use-modules (gnu build linux-initrd)) | |
1c96c1bb | 78 | |
4ee96a79 LC |
79 | (mkdir #$output) |
80 | (build-initrd (string-append #$output "/initrd") | |
81 | #:guile #$guile | |
82 | #:init #$init | |
83 | ;; Copy everything INIT refers to into the initrd. | |
84 | #:references-graphs '("closure") | |
85 | #:gzip (string-append #$gzip "/bin/gzip"))))) | |
f09d925b | 86 | |
4ee96a79 LC |
87 | (gexp->derivation name builder |
88 | #:references-graphs `(("closure" ,init))))) | |
735c6dd7 | 89 | |
b21a1c5a LC |
90 | (define (flat-linux-module-directory linux modules) |
91 | "Return a flat directory containing the Linux kernel modules listed in | |
92 | MODULES and taken from LINUX." | |
93 | (define build-exp | |
239c6e27 LC |
94 | (with-imported-modules (source-module-closure |
95 | '((guix build utils) | |
96 | (gnu build linux-modules))) | |
4ee96a79 LC |
97 | #~(begin |
98 | (use-modules (ice-9 match) (ice-9 regex) | |
99 | (srfi srfi-1) | |
100 | (guix build utils) | |
101 | (gnu build linux-modules)) | |
b21a1c5a | 102 | |
4ee96a79 LC |
103 | (define (string->regexp str) |
104 | ;; Return a regexp that matches STR exactly. | |
105 | (string-append "^" (regexp-quote str) "$")) | |
b21a1c5a | 106 | |
4ee96a79 LC |
107 | (define module-dir |
108 | (string-append #$linux "/lib/modules")) | |
b21a1c5a | 109 | |
4ee96a79 LC |
110 | (define (lookup module) |
111 | (let ((name (ensure-dot-ko module))) | |
112 | (match (find-files module-dir (string->regexp name)) | |
113 | ((file) | |
114 | file) | |
115 | (() | |
116 | (error "module not found" name module-dir)) | |
117 | ((_ ...) | |
118 | (error "several modules by that name" | |
119 | name module-dir))))) | |
600c285b | 120 | |
4ee96a79 LC |
121 | (define modules |
122 | (let ((modules (map lookup '#$modules))) | |
123 | (append modules | |
124 | (recursive-module-dependencies modules | |
125 | #:lookup-module lookup)))) | |
600c285b | 126 | |
4ee96a79 LC |
127 | (mkdir #$output) |
128 | (for-each (lambda (module) | |
129 | (format #t "copying '~a'...~%" module) | |
130 | (copy-file module | |
131 | (string-append #$output "/" | |
132 | (basename module)))) | |
133 | (delete-duplicates modules))))) | |
b21a1c5a | 134 | |
4ee96a79 | 135 | (gexp->derivation "linux-modules" build-exp)) |
b21a1c5a | 136 | |
47bdc5a1 MO |
137 | (define* (raw-initrd file-systems |
138 | #:key | |
139 | (linux linux-libre) | |
140 | (linux-modules '()) | |
141 | (mapped-devices '()) | |
142 | (helper-packages '()) | |
143 | qemu-networking? | |
144 | volatile-root?) | |
145 | "Return a monadic derivation that builds a raw initrd, with kernel | |
146 | modules taken from LINUX. FILE-SYSTEMS is a list of file-systems to be | |
147 | mounted by the initrd, possibly in addition to the root file system specified | |
148 | on the kernel command line via '--root'. LINUX-MODULES is a list of kernel | |
149 | modules to be loaded at boot time. MAPPED-DEVICES is a list of device | |
150 | mappings to realize before FILE-SYSTEMS are mounted. | |
151 | HELPER-PACKAGES is a list of packages to be copied in the initrd. It may include | |
152 | e2fsck/static or other packages needed by the initrd to check root partition. | |
153 | ||
154 | When QEMU-NETWORKING? is true, set up networking with the standard QEMU | |
155 | parameters. | |
156 | When VOLATILE-ROOT? is true, the root file system is writable but any changes | |
157 | to it are lost." | |
158 | (define device-mapping-commands | |
159 | ;; List of gexps to open the mapped devices. | |
160 | (map (lambda (md) | |
161 | (let* ((source (mapped-device-source md)) | |
162 | (target (mapped-device-target md)) | |
163 | (type (mapped-device-type md)) | |
164 | (open (mapped-device-kind-open type))) | |
165 | (open source target))) | |
166 | mapped-devices)) | |
167 | ||
168 | (mlet %store-monad ((kodir (flat-linux-module-directory linux | |
169 | linux-modules))) | |
170 | (expression->initrd | |
171 | (with-imported-modules (source-module-closure | |
172 | '((gnu build linux-boot) | |
173 | (guix build utils) | |
174 | (guix build bournish) | |
175 | (gnu build file-systems))) | |
176 | #~(begin | |
177 | (use-modules (gnu build linux-boot) | |
178 | (guix build utils) | |
179 | (guix build bournish) ;add the 'bournish' meta-command | |
180 | (srfi srfi-26) | |
181 | ||
182 | ;; FIXME: The following modules are for | |
183 | ;; LUKS-DEVICE-MAPPING. We should instead propagate | |
184 | ;; this info via gexps. | |
185 | ((gnu build file-systems) | |
186 | #:select (find-partition-by-luks-uuid)) | |
187 | (rnrs bytevectors)) | |
188 | ||
189 | (with-output-to-port (%make-void-port "w") | |
190 | (lambda () | |
191 | (set-path-environment-variable "PATH" '("bin" "sbin") | |
192 | '#$helper-packages))) | |
193 | ||
194 | (boot-system #:mounts '#$(map file-system->spec file-systems) | |
195 | #:pre-mount (lambda () | |
196 | (and #$@device-mapping-commands)) | |
197 | #:linux-modules '#$linux-modules | |
198 | #:linux-module-directory '#$kodir | |
199 | #:qemu-guest-networking? #$qemu-networking? | |
200 | #:volatile-root? '#$volatile-root?))) | |
201 | #:name "raw-initrd"))) | |
202 | ||
278d486b LC |
203 | (define* (file-system-packages file-systems #:key (volatile-root? #f)) |
204 | "Return the list of statically-linked, stripped packages to check | |
205 | FILE-SYSTEMS." | |
206 | `(,@(if (find (lambda (fs) | |
207 | (string-prefix? "ext" (file-system-type fs))) | |
208 | file-systems) | |
209 | (list e2fsck/static) | |
210 | '()) | |
211 | ,@(if (find (lambda (fs) | |
212 | (string-suffix? "fat" (file-system-type fs))) | |
213 | file-systems) | |
214 | (list fatfsck/static) | |
215 | '()) | |
216 | ,@(if (find (file-system-type-predicate "btrfs") file-systems) | |
217 | (list btrfs-progs/static) | |
218 | '()) | |
219 | ,@(if volatile-root? | |
220 | (list unionfs-fuse/static) | |
221 | '()))) | |
222 | ||
060238ae | 223 | (define* (base-initrd file-systems |
83bcd0b8 | 224 | #:key |
0d275f4a | 225 | (linux linux-libre) |
de1c158f | 226 | (mapped-devices '()) |
4fc96187 | 227 | qemu-networking? |
24e0160a | 228 | volatile-root? |
47bdc5a1 | 229 | (virtio? #t) |
6c1df081 | 230 | (extra-modules '())) |
0d275f4a AW |
231 | "Return a monadic derivation that builds a generic initrd, with kernel |
232 | modules taken from LINUX. FILE-SYSTEMS is a list of file-systems to be | |
233 | mounted by the initrd, possibly in addition to the root file system specified | |
234 | on the kernel command line via '--root'. MAPPED-DEVICES is a list of device | |
235 | mappings to realize before FILE-SYSTEMS are mounted. | |
f09d925b | 236 | |
47bdc5a1 MO |
237 | QEMU-NETWORKING? and VOLATILE-ROOT? behaves as in raw-initrd. |
238 | ||
239 | When VIRTIO? is true, load additional modules so the initrd can | |
e26d5076 LC |
240 | be used as a QEMU guest with the root file system on a para-virtualized block |
241 | device. | |
112440a7 | 242 | |
fa16f845 LC |
243 | The initrd is automatically populated with all the kernel modules necessary |
244 | for FILE-SYSTEMS and for the given options. However, additional kernel | |
245 | modules can be listed in EXTRA-MODULES. They will be added to the initrd, and | |
6c1df081 | 246 | loaded at boot time in the order in which they appear." |
24e0160a LC |
247 | (define virtio-modules |
248 | ;; Modules for Linux para-virtualized devices, for use in QEMU guests. | |
a182e94e LC |
249 | '("virtio_pci" "virtio_balloon" "virtio_blk" "virtio_net" |
250 | "virtio_console")) | |
24e0160a | 251 | |
d4254711 LC |
252 | (define cifs-modules |
253 | ;; Modules needed to mount CIFS file systems. | |
08b1990a | 254 | '("md4" "ecb" "cifs")) |
88840f02 | 255 | |
4919d684 LC |
256 | (define virtio-9p-modules |
257 | ;; Modules for the 9p paravirtualized file system. | |
08b1990a | 258 | '("9p" "9pnet_virtio")) |
4919d684 | 259 | |
83bcd0b8 LC |
260 | (define (file-system-type-predicate type) |
261 | (lambda (fs) | |
262 | (string=? (file-system-type fs) type))) | |
263 | ||
d4254711 LC |
264 | (define linux-modules |
265 | ;; Modules added to the initrd and loaded from the initrd. | |
493c245b | 266 | `("ahci" ;for SATA controllers |
493c245b | 267 | "usb-storage" "uas" ;for the installation image etc. |
cc023e32 | 268 | "usbhid" "hid-generic" "hid-apple" ;keyboards during early boot |
dfb9001a | 269 | "dm-crypt" "xts" "serpent_generic" "wp512" ;for encrypted root partitions |
ad857912 | 270 | "nvme" ;for new SSD NVMe devices |
9f4a2496 MW |
271 | ,@(if (string-match "^(x86_64|i[3-6]86)-" (%current-system)) |
272 | '("pata_acpi" "pata_atiixp" ;for ATA controllers | |
273 | "isci") ;for SAS controllers like Intel C602 | |
274 | '()) | |
c299dffc | 275 | ,@(if (or virtio? qemu-networking?) |
24e0160a LC |
276 | virtio-modules |
277 | '()) | |
83bcd0b8 | 278 | ,@(if (find (file-system-type-predicate "cifs") file-systems) |
4919d684 LC |
279 | cifs-modules |
280 | '()) | |
83bcd0b8 | 281 | ,@(if (find (file-system-type-predicate "9p") file-systems) |
4919d684 | 282 | virtio-9p-modules |
1c96c1bb | 283 | '()) |
866872aa MB |
284 | ,@(if (find (file-system-type-predicate "vfat") file-systems) |
285 | '("nls_iso8859-1") | |
286 | '()) | |
b1a505ba DC |
287 | ,@(if (find (file-system-type-predicate "btrfs") file-systems) |
288 | '("btrfs") | |
289 | '()) | |
1c96c1bb | 290 | ,@(if volatile-root? |
08b1990a | 291 | '("fuse") |
fa16f845 LC |
292 | '()) |
293 | ,@extra-modules)) | |
f09d925b | 294 | |
3c05b4bc | 295 | (define helper-packages |
72089954 | 296 | (file-system-packages file-systems #:volatile-root? volatile-root?)) |
3c05b4bc | 297 | |
47bdc5a1 MO |
298 | (raw-initrd file-systems |
299 | #:linux linux | |
300 | #:linux-modules linux-modules | |
301 | #:mapped-devices mapped-devices | |
302 | #:helper-packages helper-packages | |
303 | #:qemu-networking? qemu-networking? | |
304 | #:volatile-root? volatile-root?)) | |
f09d925b LC |
305 | |
306 | ;;; linux-initrd.scm ends here |