file-systems: Add missing docstring.
[jackhill/guix/guix.git] / gnu / system / linux-initrd.scm
CommitLineData
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 65containing GUILE and that evaluates EXP, a G-expression, upon booting. All
4ee96a79 66the 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
92MODULES 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
146modules taken from LINUX. FILE-SYSTEMS is a list of file-systems to be
147mounted by the initrd, possibly in addition to the root file system specified
148on the kernel command line via '--root'. LINUX-MODULES is a list of kernel
149modules to be loaded at boot time. MAPPED-DEVICES is a list of device
150mappings to realize before FILE-SYSTEMS are mounted.
151HELPER-PACKAGES is a list of packages to be copied in the initrd. It may include
152e2fsck/static or other packages needed by the initrd to check root partition.
153
154When QEMU-NETWORKING? is true, set up networking with the standard QEMU
155parameters.
156When VOLATILE-ROOT? is true, the root file system is writable but any changes
157to 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
205FILE-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
232modules taken from LINUX. FILE-SYSTEMS is a list of file-systems to be
233mounted by the initrd, possibly in addition to the root file system specified
234on the kernel command line via '--root'. MAPPED-DEVICES is a list of device
235mappings to realize before FILE-SYSTEMS are mounted.
f09d925b 236
47bdc5a1
MO
237QEMU-NETWORKING? and VOLATILE-ROOT? behaves as in raw-initrd.
238
239When VIRTIO? is true, load additional modules so the initrd can
e26d5076
LC
240be used as a QEMU guest with the root file system on a para-virtualized block
241device.
112440a7 242
fa16f845
LC
243The initrd is automatically populated with all the kernel modules necessary
244for FILE-SYSTEMS and for the given options. However, additional kernel
245modules can be listed in EXTRA-MODULES. They will be added to the initrd, and
6c1df081 246loaded 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