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=0xfwip/yesman
parent
e47fe46e03
commit
6d176afe5e
@ -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"; |
||||
}; |
||||
} |
@ -0,0 +1,8 @@ |
||||
{ pkgs }: |
||||
|
||||
pkgs.substituteAll { |
||||
src = ./extlinux-conf-builder.sh; |
||||
isExecutable = true; |
||||
inherit (pkgs) bash; |
||||
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep]; |
||||
} |
@ -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 |
Loading…
Reference in new issue