summaryrefslogtreecommitdiffstats
path: root/nixos/modules/system/boot/loader/generic-extlinux-compatible
diff options
context:
space:
mode:
authorTuomas Tynkkynen <tuomas.tynkkynen@iki.fi>2015-05-02 05:56:48 +0300
committerTuomas Tynkkynen <tuomas.tynkkynen@iki.fi>2015-05-17 23:38:03 +0300
commit6d176afe5e3664e2a522afcc59c5dc3a5b40c455 (patch)
tree7f1fe38eacac21844d70410800137fb0b07a2e9b /nixos/modules/system/boot/loader/generic-extlinux-compatible
parente47fe46e031d2df000f2baee598b2553e5ca93f6 (diff)
generic-extlinux-compatible: Add new bootloader for ARM
This module generates a /boot/extlinux/extlinux.conf bootloader configuration file that is supported by e.g. U-Boot: http://git.denx.de/?p=u-boot.git;a=blob;f=doc/README.distro;hb=refs/heads/master With this, all ARM boards supported by U-Boot can be booted in a common way (a single boot file generator, all boards booting via initrd like x86) and with same boot menu functionality as GRUB has. -- sample extlinux.conf file -- # Generated file, all changes will be lost on nixos-rebuild! # Change this to e.g. nixos-42 to temporarily boot to an older configuration. DEFAULT nixos-default TIMEOUT 50 LABEL nixos-default MENU LABEL NixOS - Default LINUX ../nixos/n7vxfk60nb5h0mcbhkwwxhcz2q2nvxzv-linux-4.1.0-rc3-cpufreq-zImage INITRD ../nixos/0ss2zs8sb6d1qn4gblxpwlxkfjsgs5f0-initrd-initrd FDTDIR ../nixos/n7vxfk60nb5h0mcbhkwwxhcz2q2nvxzv-linux-4.1.0-rc3-cpufreq-dtbs APPEND systemConfig=/nix/store/469qvr43ln8bfsnk5lzcz6m6jfcgdd4r-nixos-15.06.git.0b7a7a6M init=/nix/store/469qvr43ln8bfsnk5lzcz6m6jfcgdd4r-nixos-15.06.git.0b7a7a6M/init loglevel=8 console=ttyS0,115200n8 drm.debug=0xf LABEL nixos-71 MENU LABEL NixOS - Configuration 71 (2015-05-17 21:32 - 15.06.git.0b7a7a6M) LINUX ../nixos/n7vxfk60nb5h0mcbhkwwxhcz2q2nvxzv-linux-4.1.0-rc3-cpufreq-zImage INITRD ../nixos/0ss2zs8sb6d1qn4gblxpwlxkfjsgs5f0-initrd-initrd FDTDIR ../nixos/n7vxfk60nb5h0mcbhkwwxhcz2q2nvxzv-linux-4.1.0-rc3-cpufreq-dtbs APPEND systemConfig=/nix/store/469qvr43ln8bfsnk5lzcz6m6jfcgdd4r-nixos-15.06.git.0b7a7a6M init=/nix/store/469qvr43ln8bfsnk5lzcz6m6jfcgdd4r-nixos-15.06.git.0b7a7a6M/init loglevel=8 console=ttyS0,115200n8 drm.debug=0xf
Diffstat (limited to 'nixos/modules/system/boot/loader/generic-extlinux-compatible')
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix44
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix8
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh132
3 files changed, 184 insertions, 0 deletions
diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
new file mode 100644
index 000000000000..af39c7bb6841
--- /dev/null
+++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
@@ -0,0 +1,44 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ blCfg = config.boot.loader;
+ cfg = blCfg.generic-extlinux-compatible;
+
+ timeoutStr = if blCfg.timeout == null then "-1" else toString blCfg.timeout;
+
+ builder = import ./extlinux-conf-builder.nix { inherit pkgs; };
+in
+{
+ options = {
+ boot.loader.generic-extlinux-compatible = {
+ enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether to generate an extlinux-compatible configuration file
+ under <literal>/boot/extlinux.conf</literal>. For instance,
+ U-Boot's generic distro boot support uses this file format.
+
+ See <link xlink:href="http://git.denx.de/?p=u-boot.git;a=blob;f=doc/README.distro;hb=refs/heads/master">U-boot's documentation</link>
+ for more information.
+ '';
+ };
+
+ configurationLimit = mkOption {
+ default = 20;
+ example = 10;
+ type = types.int;
+ description = ''
+ Maximum number of configurations in the boot menu.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ system.build.installBootLoader = "${builder} -g ${toString cfg.configurationLimit} -t ${timeoutStr} -c";
+ system.boot.loader.id = "generic-extlinux-compatible";
+ };
+}
diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
new file mode 100644
index 000000000000..261192c6d24e
--- /dev/null
+++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
@@ -0,0 +1,8 @@
+{ pkgs }:
+
+pkgs.substituteAll {
+ src = ./extlinux-conf-builder.sh;
+ isExecutable = true;
+ inherit (pkgs) bash;
+ path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
+}
diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
new file mode 100644
index 000000000000..8f2a496de8b6
--- /dev/null
+++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
@@ -0,0 +1,132 @@
+#! @bash@/bin/sh -e
+
+shopt -s nullglob
+
+export PATH=/empty
+for i in @path@; do PATH=$PATH:$i/bin; done
+
+usage() {
+ echo "usage: $0 -t <timeout> -c <path-to-default-configuration> [-d <boot-dir>] [-g <num-generations>]" >&2
+ exit 1
+}
+
+timeout= # Timeout in centiseconds
+default= # Default configuration
+target=/boot # Target directory
+numGenerations=0 # Number of other generations to include in the menu
+
+while getopts "t:c:d:g:" opt; do
+ case "$opt" in
+ t) # U-Boot interprets '0' as infinite and negative as instant boot
+ if [ "$OPTARG" -lt 0 ]; then
+ timeout=0
+ elif [ "$OPTARG" = 0 ]; then
+ timeout=-10
+ else
+ timeout=$((OPTARG * 10))
+ fi
+ ;;
+ c) default="$OPTARG" ;;
+ d) target="$OPTARG" ;;
+ g) numGenerations="$OPTARG" ;;
+ \?) usage ;;
+ esac
+done
+
+[ "$timeout" = "" -o "$default" = "" ] && usage
+
+mkdir -p $target/nixos
+mkdir -p $target/extlinux
+
+# Convert a path to a file in the Nix store such as
+# /nix/store/<hash>-<name>/file to <hash>-<name>-<file>.
+cleanName() {
+ local path="$1"
+ echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g'
+}
+
+# Copy a file from the Nix store to $target/nixos.
+declare -A filesCopied
+
+copyToKernelsDir() {
+ local src=$(readlink -f "$1")
+ local dst="$target/nixos/$(cleanName $src)"
+ # Don't copy the file if $dst already exists. This means that we
+ # have to create $dst atomically to prevent partially copied
+ # kernels or initrd if this script is ever interrupted.
+ if ! test -e $dst; then
+ local dstTmp=$dst.tmp.$$
+ cp -r $src $dstTmp
+ mv $dstTmp $dst
+ fi
+ filesCopied[$dst]=1
+ result=$dst
+}
+
+# Copy its kernel, initrd and dtbs to $target/nixos, and echo out an
+# extlinux menu entry
+addEntry() {
+ local path=$(readlink -f "$1")
+ local tag="$2" # Generation number or 'default'
+
+ if ! test -e $path/kernel -a -e $path/initrd; then
+ return
+ fi
+
+ copyToKernelsDir "$path/kernel"; kernel=$result
+ copyToKernelsDir "$path/initrd"; initrd=$result
+ # XXX UGLY: maybe the system config should have a top-level "dtbs" entry?
+ copyToKernelsDir $(readlink -m "$path/kernel/../dtbs"); dtbs=$result
+
+ timestampEpoch=$(stat -L -c '%Z' $path)
+
+ timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch)
+ nixosVersion="$(cat $path/nixos-version)"
+ extraParams="$(cat $path/kernel-params)"
+
+ echo
+ echo "LABEL nixos-$tag"
+ if [ "$tag" = "default" ]; then
+ echo " MENU LABEL NixOS - Default"
+ else
+ echo " MENU LABEL NixOS - Configuration $tag ($timestamp - $nixosVersion)"
+ fi
+ echo " LINUX ../nixos/$(basename $kernel)"
+ echo " INITRD ../nixos/$(basename $initrd)"
+ echo " FDTDIR ../nixos/$(basename $dtbs)"
+ echo " APPEND systemConfig=$path init=$path/init $extraParams"
+}
+
+tmpFile="$target/extlinux/extlinux.conf.tmp.$$"
+
+cat > $tmpFile <<EOF
+# Generated file, all changes will be lost on nixos-rebuild!
+
+# Change this to e.g. nixos-42 to temporarily boot to an older configuration.
+DEFAULT nixos-default
+
+TIMEOUT $timeout
+$(addEntry $default default)
+EOF
+
+# Add up to $numGenerations generations of the system profile to the menu,
+# in reverse (most recent to least recent) order.
+for generation in $(
+ (cd /nix/var/nix/profiles && ls -d system-*-link) \
+ | sed 's/system-\([0-9]\+\)-link/\1/' \
+ | sort -n -r \
+ | head -n $numGenerations); do
+ link=/nix/var/nix/profiles/system-$generation-link
+ addEntry $link $generation
+done >> $tmpFile
+
+mv -f $tmpFile $target/extlinux/extlinux.conf
+
+# Remove obsolete files from $target/nixos.
+for fn in $target/nixos/*; do
+ if ! test "${filesCopied[$fn]}" = 1; then
+ echo "Removing no longer needed boot file: $fn"
+ chmod +w -- "$fn"
+ rm -rf -- "$fn"
+ fi
+done