system: Add support for Linux-style mapped devices.
[jackhill/guix/guix.git] / gnu / system / linux-initrd.scm
CommitLineData
f09d925b 1;;; GNU Guix --- Functional package management for GNU
b0dd47a8 2;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
f09d925b
LC
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
735c6dd7
LC
19(define-module (gnu system linux-initrd)
20 #:use-module (guix monads)
0c21d92b 21 #:use-module (guix gexp)
f09d925b 22 #:use-module (guix utils)
d4254711
LC
23 #:use-module ((guix store)
24 #:select (%store-prefix))
1c96c1bb
LC
25 #:use-module ((guix derivations)
26 #:select (derivation->output-path))
f09d925b
LC
27 #:use-module (gnu packages cpio)
28 #:use-module (gnu packages compression)
29 #:use-module (gnu packages linux)
f989fa39 30 #:use-module (gnu packages guile)
f09d925b
LC
31 #:use-module ((gnu packages make-bootstrap)
32 #:select (%guile-static-stripped))
c5df1839 33 #:use-module (gnu system file-systems)
1c96c1bb 34 #:use-module (ice-9 match)
217b862f 35 #:use-module (ice-9 regex)
83bcd0b8 36 #:use-module (srfi srfi-1)
42d10464 37 #:use-module (srfi srfi-26)
735c6dd7 38 #:export (expression->initrd
060238ae 39 base-initrd))
f09d925b
LC
40
41\f
42;;; Commentary:
43;;;
44;;; Tools to build initial RAM disks (initrd's) for Linux-Libre, and in
45;;; particular initrd's that run Guile.
46;;;
47;;; Code:
48
49
50(define* (expression->initrd exp
51 #:key
52 (guile %guile-static-stripped)
53 (cpio cpio)
54 (gzip gzip)
55 (name "guile-initrd")
56 (system (%current-system))
42d10464 57 (modules '()))
fd1b1fa2 58 "Return a derivation that builds a Linux initrd (a gzipped cpio archive)
df650fa8
LC
59containing GUILE and that evaluates EXP, a G-expression, upon booting. All
60the derivations referenced by EXP are automatically copied to the initrd.
fd1b1fa2 61
42d10464 62MODULES is a list of Guile module names to be embedded in the initrd."
f09d925b
LC
63
64 ;; General Linux overview in `Documentation/early-userspace/README' and
65 ;; `Documentation/filesystems/ramfs-rootfs-initramfs.txt'.
66
42d10464
LC
67 (mlet %store-monad ((init (gexp->script "init" exp
68 #:modules modules
69 #:guile guile)))
0c21d92b 70 (define builder
0c21d92b 71 #~(begin
1621cf97 72 (use-modules (gnu build linux-initrd))
1c96c1bb 73
70608adb 74 (mkdir #$output)
1621cf97
LC
75 (build-initrd (string-append #$output "/initrd")
76 #:guile #$guile
77 #:init #$init
42d10464 78 ;; Copy everything INIT refers to into the initrd.
df650fa8 79 #:references-graphs '("closure")
1621cf97
LC
80 #:cpio (string-append #$cpio "/bin/cpio")
81 #:gzip (string-append #$gzip "/bin/gzip"))))
f09d925b 82
0c21d92b 83 (gexp->derivation name builder
fbb35558 84 #:modules '((guix build utils)
49fa9381
LC
85 (guix build store-copy)
86 (gnu build linux-initrd))
df650fa8 87 #:references-graphs `(("closure" ,init)))))
735c6dd7 88
b21a1c5a
LC
89(define (flat-linux-module-directory linux modules)
90 "Return a flat directory containing the Linux kernel modules listed in
91MODULES and taken from LINUX."
92 (define build-exp
93 #~(begin
94 (use-modules (ice-9 match) (ice-9 regex)
95 (guix build utils))
96
97 (define (string->regexp str)
98 ;; Return a regexp that matches STR exactly.
99 (string-append "^" (regexp-quote str) "$"))
100
101 (define module-dir
102 (string-append #$linux "/lib/modules"))
103
104 (mkdir #$output)
105 (for-each (lambda (module)
106 (match (find-files module-dir (string->regexp module))
107 ((file)
108 (format #t "copying '~a'...~%" file)
109 (copy-file file (string-append #$output "/" module)))
110 (()
111 (error "module not found" module module-dir))
112 ((_ ...)
113 (error "several modules by that name"
114 module module-dir))))
115 '#$modules)))
116
117 (gexp->derivation "linux-modules" build-exp
118 #:modules '((guix build utils))))
119
83bcd0b8
LC
120(define (file-system->spec fs)
121 "Return a list corresponding to file-system FS that can be passed to the
122initrd code."
123 (match fs
d4c87617
LC
124 (($ <file-system> device title mount-point type flags options _ check?)
125 (list device title mount-point type flags options check?))))
83bcd0b8 126
060238ae 127(define* (base-initrd file-systems
83bcd0b8 128 #:key
4fc96187 129 qemu-networking?
24e0160a
LC
130 virtio?
131 volatile-root?
fa16f845 132 (extra-modules '())
24e0160a 133 guile-modules-in-chroot?)
5dae0186 134 ;; TODO: Support boot-time device mappings.
060238ae
LC
135 "Return a monadic derivation that builds a generic initrd. FILE-SYSTEMS is
136a list of file-systems to be mounted by the initrd, possibly in addition to
137the root file system specified on the kernel command line via '--root'.
f09d925b 138
112440a7 139When QEMU-NETWORKING? is true, set up networking with the standard QEMU
24e0160a
LC
140parameters. When VIRTIO? is true, load additional modules so the initrd can
141be used as a QEMU guest with para-virtualized I/O drivers.
112440a7 142
83bcd0b8
LC
143When VOLATILE-ROOT? is true, the root file system is writable but any changes
144to it are lost.
b48d21b2 145
fa16f845
LC
146The initrd is automatically populated with all the kernel modules necessary
147for FILE-SYSTEMS and for the given options. However, additional kernel
148modules can be listed in EXTRA-MODULES. They will be added to the initrd, and
149loaded at boot time in the order in which they appear.
150
d4254711
LC
151When GUILE-MODULES-IN-CHROOT? is true, make core Guile modules available in
152the new root. This is necessary is the file specified as '--load' needs
153access to these modules (which is the case if it wants to even just print an
83bcd0b8 154exception and backtrace!)."
24e0160a
LC
155 (define virtio-modules
156 ;; Modules for Linux para-virtualized devices, for use in QEMU guests.
157 '("virtio.ko" "virtio_ring.ko" "virtio_pci.ko"
158 "virtio_balloon.ko" "virtio_blk.ko" "virtio_net.ko"))
159
d4254711
LC
160 (define cifs-modules
161 ;; Modules needed to mount CIFS file systems.
162 '("md4.ko" "ecb.ko" "cifs.ko"))
88840f02 163
4919d684
LC
164 (define virtio-9p-modules
165 ;; Modules for the 9p paravirtualized file system.
6f22f3c9 166 '("fscache.ko" "9pnet.ko" "9p.ko" "9pnet_virtio.ko"))
4919d684 167
83bcd0b8
LC
168 (define (file-system-type-predicate type)
169 (lambda (fs)
170 (string=? (file-system-type fs) type)))
171
d4254711
LC
172 (define linux-modules
173 ;; Modules added to the initrd and loaded from the initrd.
c299dffc
DT
174 `("libahci.ko" "ahci.ko" ; modules for SATA controllers
175 ,@(if (or virtio? qemu-networking?)
24e0160a
LC
176 virtio-modules
177 '())
83bcd0b8 178 ,@(if (find (file-system-type-predicate "cifs") file-systems)
4919d684
LC
179 cifs-modules
180 '())
83bcd0b8 181 ,@(if (find (file-system-type-predicate "9p") file-systems)
4919d684 182 virtio-9p-modules
1c96c1bb
LC
183 '())
184 ,@(if volatile-root?
185 '("fuse.ko")
fa16f845
LC
186 '())
187 ,@extra-modules))
f09d925b 188
3c05b4bc
LC
189 (define helper-packages
190 ;; Packages to be copied on the initrd.
191 `(,@(if (find (lambda (fs)
192 (string-prefix? "ext" (file-system-type fs)))
193 file-systems)
194 (list e2fsck/static)
195 '())
196 ,@(if volatile-root?
197 (list unionfs-fuse/static)
198 '())))
199
42d10464
LC
200 (mlet %store-monad ((kodir (flat-linux-module-directory linux-libre
201 linux-modules)))
202 (expression->initrd
203 #~(begin
204 (use-modules (gnu build linux-boot)
205 (guix build utils)
206 (srfi srfi-26))
207
208 (with-output-to-port (%make-void-port "w")
209 (lambda ()
210 (set-path-environment-variable "PATH" '("bin" "sbin")
211 '#$helper-packages)))
212
213 (boot-system #:mounts '#$(map file-system->spec file-systems)
214 #:linux-modules (map (lambda (file)
215 (string-append #$kodir "/" file))
216 '#$linux-modules)
217 #:qemu-guest-networking? #$qemu-networking?
218 #:guile-modules-in-chroot? '#$guile-modules-in-chroot?
219 #:volatile-root? '#$volatile-root?))
220 #:name "base-initrd"
221 #:modules '((guix build utils)
222 (gnu build linux-boot)
223 (gnu build file-systems)))))
f09d925b
LC
224
225;;; linux-initrd.scm ends here