;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see . (define-module (gnu build linux-initrd) #:use-module ((guix cpio) #:prefix cpio:) #:use-module (guix build utils) #:use-module (guix build store-copy) #:use-module (system base compile) #:use-module (rnrs bytevectors) #:use-module ((system foreign) #:select (sizeof)) #:use-module (ice-9 ftw) #:export (write-cpio-archive build-initrd)) ;;; Commentary: ;;; ;;; Tools to create Linux initial RAM disks ("initrds"). Initrds are ;;; essentially gzipped cpio archives, with a '/init' executable that the ;;; kernel runs at boot time. ;;; ;;; Code: (define* (write-cpio-archive output directory #:key (compress? #t) (gzip "gzip")) "Write a cpio archive containing DIRECTORY to file OUTPUT. When COMPRESS? is true, compress it using GZIP. On success, return OUTPUT." ;; Note: as per `ramfs-rootfs-initramfs.txt', always add directory entries ;; before the files that are inside of it: "The Linux kernel cpio ;; extractor won't create files in a directory that doesn't exist, so the ;; directory entries must go before the files that go in those ;; directories." (define files ;; Use 'sort' so that (1) the order of files is deterministic, and (2) ;; directories appear before the files they contain. (sort (file-system-fold (const #t) ;enter? (lambda (file stat result) ;leaf (cons file result)) (lambda (dir stat result) ;down (if (string=? dir directory) result (cons dir result))) (lambda (file stat result) result) (const #f) ;skip (const #f) ;error '() directory) string