forked from mirrors/nixpkgs
Making modular my previous changes for armv5tel. I updated the way to use
grub. Its options are no more inside 'boot', but inside 'boot.loader.grub'. I added a new bootloader configuration for nixos, generationsDir. It creates /boot/default/{init,initrd,kernel,system} symlinks, and the same for the generations in /boot/system-$gen/{init,initrd,kernel,system}. I can program the u-boot loader to load /boot/default files always, and have a minimal nixos boot loader installer functionality. Additionally, I can refer to the other system generations easily, with a simple 'ls' in /boot. svn path=/nixos/trunk/; revision=17460
This commit is contained in:
parent
852478ff79
commit
75f6cd20da
|
@ -60,7 +60,7 @@ let
|
||||||
pkgs.usbutils
|
pkgs.usbutils
|
||||||
pkgs.utillinux
|
pkgs.utillinux
|
||||||
pkgs.wirelesstools
|
pkgs.wirelesstools
|
||||||
] ++ optional (pkgs.stdenv.system != "armv5tel-linux") [ pkgs.grub ]
|
]
|
||||||
++ config.environment.extraPackages;
|
++ config.environment.extraPackages;
|
||||||
|
|
||||||
|
|
||||||
|
|
105
modules/installer/generations-dir/generations-dir-builder.sh
Normal file
105
modules/installer/generations-dir/generations-dir-builder.sh
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#! @bash@/bin/sh -e
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
export PATH=/empty
|
||||||
|
for i in @path@; do PATH=$PATH:$i/bin; done
|
||||||
|
|
||||||
|
default=$1
|
||||||
|
if test -z "$1"; then
|
||||||
|
echo "Syntax: generations-dir-builder.sh <DEFAULT-CONFIG>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "updating the boot generations directory..."
|
||||||
|
|
||||||
|
mkdir -p /boot
|
||||||
|
|
||||||
|
rm -Rf /boot/system* || true
|
||||||
|
|
||||||
|
target=/boot/grub/menu.lst
|
||||||
|
tmp=$target.tmp
|
||||||
|
|
||||||
|
# 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 /boot/kernels.
|
||||||
|
declare -A filesCopied
|
||||||
|
|
||||||
|
copyToKernelsDir() {
|
||||||
|
local src="$1"
|
||||||
|
local dst="/boot/kernels/$(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 $src $dstTmp
|
||||||
|
mv $dstTmp $dst
|
||||||
|
fi
|
||||||
|
filesCopied[$dst]=1
|
||||||
|
result=$dst
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Add an entry for a configuration to the Grub menu, and if
|
||||||
|
# appropriate, copy its kernel and initrd to /boot/kernels.
|
||||||
|
addEntry() {
|
||||||
|
local path="$1"
|
||||||
|
local generation="$2"
|
||||||
|
local outdir=/boot/system-$generation
|
||||||
|
|
||||||
|
if ! test -e $path/kernel -a -e $path/initrd; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local kernel=$(readlink -f $path/kernel)
|
||||||
|
local initrd=$(readlink -f $path/initrd)
|
||||||
|
|
||||||
|
if test -n "@copyKernels@"; then
|
||||||
|
copyToKernelsDir $kernel; kernel=$result
|
||||||
|
copyToKernelsDir $initrd; initrd=$result
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p $outdir
|
||||||
|
ln -sf $(readlink -f $path) $outdir/system
|
||||||
|
ln -sf $(readlink -f $path/init) $outdir/init
|
||||||
|
ln -sf $(readlink -f $path/initrd) $outdir/initrd
|
||||||
|
ln -sf $(readlink -f $path/kernel) $outdir/kernel
|
||||||
|
|
||||||
|
if test $(readlink -f "$path") = "$default"; then
|
||||||
|
cp "$kernel" /boot/nixos-kernel
|
||||||
|
cp "$initrd" /boot/nixos-initrd
|
||||||
|
cp "$(readlink -f "$path/init")" /boot/nixos-init
|
||||||
|
mkdir -p /boot/default
|
||||||
|
ln -sf $(readlink -f $path) /boot/default/system
|
||||||
|
ln -sf $(readlink -f $path/init) /boot/default/init
|
||||||
|
ln -sf $(readlink -f $path/initrd) /boot/default/initrd
|
||||||
|
ln -sf $(readlink -f $path/kernel) /boot/default/kernel
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if test -n "@copyKernels@"; then
|
||||||
|
mkdir -p /boot/kernels
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add all 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); do
|
||||||
|
link=/nix/var/nix/profiles/system-$generation-link
|
||||||
|
addEntry $link $generation
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove obsolete files from /boot/kernels.
|
||||||
|
for fn in /boot/kernels/*; do
|
||||||
|
if ! test "${filesCopied[$fn]}" = 1; then
|
||||||
|
rm -vf -- "$fn"
|
||||||
|
fi
|
||||||
|
done
|
60
modules/installer/generations-dir/generations-dir.nix
Normal file
60
modules/installer/generations-dir/generations-dir.nix
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{pkgs, config, ...}:
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
let
|
||||||
|
inherit (pkgs.lib) mkOption mkIf;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
boot = {
|
||||||
|
loader = {
|
||||||
|
generationsDir = {
|
||||||
|
|
||||||
|
enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable the simple preparation of symlinks to the system
|
||||||
|
generations in /boot.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
copyKernels = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = "
|
||||||
|
Whether copy the necessary boot files into /boot, so
|
||||||
|
/nix/store is not needed by the boot loadear.
|
||||||
|
";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
let
|
||||||
|
generationsDirBuilder = pkgs.substituteAll {
|
||||||
|
src = ./generations-dir-builder.sh;
|
||||||
|
isExecutable = true;
|
||||||
|
inherit (pkgs) bash;
|
||||||
|
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
|
||||||
|
inherit (config.boot.loader.generationsDir) copyKernels;
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
require = [
|
||||||
|
options
|
||||||
|
|
||||||
|
# config.system.build
|
||||||
|
# ../system/system-options.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
system = mkIf config.boot.loader.generationsDir.enable {
|
||||||
|
build = {
|
||||||
|
menuBuilder = generationsDirBuilder;
|
||||||
|
};
|
||||||
|
boot.loader.id = "generationsDir";
|
||||||
|
boot.loader.kernelFile = "uImage";
|
||||||
|
};
|
||||||
|
}
|
|
@ -2,90 +2,100 @@
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
let
|
let
|
||||||
inherit (pkgs.lib) mkOption;
|
inherit (pkgs.lib) mkOption mkIf;
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
boot = {
|
boot = {
|
||||||
|
loader = {
|
||||||
|
grub = {
|
||||||
|
|
||||||
grubDevice = mkOption {
|
enable = mkOption {
|
||||||
default = "";
|
default = true;
|
||||||
example = "/dev/hda";
|
description = ''
|
||||||
description = "
|
Whether to enable the GRUB boot loader.
|
||||||
The device on which the boot loader, Grub, will be installed.
|
'';
|
||||||
If empty, Grub won't be installed and it's your responsibility
|
};
|
||||||
to make the system bootable.
|
|
||||||
";
|
|
||||||
};
|
|
||||||
|
|
||||||
bootMount = mkOption {
|
grubDevice = mkOption {
|
||||||
default = "";
|
default = "";
|
||||||
example = "(hd0,0)";
|
example = "/dev/hda";
|
||||||
description = "
|
description = "
|
||||||
If the system partition may be wiped on reinstall, it is better
|
The device on which the boot loader, Grub, will be installed.
|
||||||
to have /boot on a small partition. To do it, we need to explain
|
If empty, Grub won't be installed and it's your responsibility
|
||||||
to GRUB where the kernels live. Specify the partition here (in
|
to make the system bootable.
|
||||||
GRUB notation.
|
";
|
||||||
";
|
};
|
||||||
};
|
|
||||||
|
|
||||||
configurationName = mkOption {
|
bootMount = mkOption {
|
||||||
default = "";
|
default = "";
|
||||||
example = "Stable 2.6.21";
|
example = "(hd0,0)";
|
||||||
description = "
|
description = "
|
||||||
Grub entry name instead of default.
|
If the system partition may be wiped on reinstall, it is better
|
||||||
";
|
to have /boot on a small partition. To do it, we need to explain
|
||||||
};
|
to GRUB where the kernels live. Specify the partition here (in
|
||||||
|
GRUB notation.
|
||||||
|
";
|
||||||
|
};
|
||||||
|
|
||||||
extraGrubEntries = mkOption {
|
configurationName = mkOption {
|
||||||
default = "";
|
default = "";
|
||||||
example = "
|
example = "Stable 2.6.21";
|
||||||
title Windows
|
description = "
|
||||||
chainloader (hd0,1)+1
|
Grub entry name instead of default.
|
||||||
";
|
";
|
||||||
description = "
|
};
|
||||||
Any additional entries you want added to the Grub boot menu.
|
|
||||||
";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraGrubEntriesBeforeNixos = mkOption {
|
extraGrubEntries = mkOption {
|
||||||
default = false;
|
default = "";
|
||||||
description = "
|
example = "
|
||||||
Wheter extraGrubEntries are put before the Nixos-default option
|
title Windows
|
||||||
";
|
chainloader (hd0,1)+1
|
||||||
};
|
";
|
||||||
|
description = "
|
||||||
|
Any additional entries you want added to the Grub boot menu.
|
||||||
|
";
|
||||||
|
};
|
||||||
|
|
||||||
grubSplashImage = mkOption {
|
extraGrubEntriesBeforeNixos = mkOption {
|
||||||
default = pkgs.fetchurl {
|
default = false;
|
||||||
url = http://www.gnome-look.org/CONTENT/content-files/36909-soft-tux.xpm.gz;
|
description = "
|
||||||
sha256 = "14kqdx2lfqvh40h6fjjzqgff1mwk74dmbjvmqphi6azzra7z8d59";
|
Wheter extraGrubEntries are put before the Nixos-default option
|
||||||
|
";
|
||||||
|
};
|
||||||
|
|
||||||
|
grubSplashImage = mkOption {
|
||||||
|
default = pkgs.fetchurl {
|
||||||
|
url = http://www.gnome-look.org/CONTENT/content-files/36909-soft-tux.xpm.gz;
|
||||||
|
sha256 = "14kqdx2lfqvh40h6fjjzqgff1mwk74dmbjvmqphi6azzra7z8d59";
|
||||||
|
};
|
||||||
|
example = null;
|
||||||
|
description = "
|
||||||
|
Background image used for Grub. It must be a 640x480,
|
||||||
|
14-colour image in XPM format, optionally compressed with
|
||||||
|
<command>gzip</command> or <command>bzip2</command>. Set to
|
||||||
|
<literal>null</literal> to run Grub in text mode.
|
||||||
|
";
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationLimit = mkOption {
|
||||||
|
default = 100;
|
||||||
|
example = 120;
|
||||||
|
description = "
|
||||||
|
Maximum of configurations in boot menu. GRUB has problems when
|
||||||
|
there are too many entries.
|
||||||
|
";
|
||||||
|
};
|
||||||
|
|
||||||
|
copyKernels = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = "
|
||||||
|
Whether the Grub menu builder should copy kernels and initial
|
||||||
|
ramdisks to /boot. This is necessary when /nix is on a
|
||||||
|
different file system than /boot.
|
||||||
|
";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
example = null;
|
|
||||||
description = "
|
|
||||||
Background image used for Grub. It must be a 640x480,
|
|
||||||
14-colour image in XPM format, optionally compressed with
|
|
||||||
<command>gzip</command> or <command>bzip2</command>. Set to
|
|
||||||
<literal>null</literal> to run Grub in text mode.
|
|
||||||
";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
configurationLimit = mkOption {
|
|
||||||
default = 100;
|
|
||||||
example = 120;
|
|
||||||
description = "
|
|
||||||
Maximum of configurations in boot menu. GRUB has problems when
|
|
||||||
there are too many entries.
|
|
||||||
";
|
|
||||||
};
|
|
||||||
|
|
||||||
copyKernels = mkOption {
|
|
||||||
default = false;
|
|
||||||
description = "
|
|
||||||
Whether the Grub menu builder should copy kernels and initial
|
|
||||||
ramdisks to /boot. This is necessary when /nix is on a
|
|
||||||
different file system than /boot.
|
|
||||||
";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
@ -99,7 +109,7 @@ let
|
||||||
isExecutable = true;
|
isExecutable = true;
|
||||||
inherit (pkgs) bash;
|
inherit (pkgs) bash;
|
||||||
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
|
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
|
||||||
inherit (config.boot) copyKernels extraGrubEntries extraGrubEntriesBeforeNixos
|
inherit (config.boot.loader.grub) copyKernels extraGrubEntries extraGrubEntriesBeforeNixos
|
||||||
grubSplashImage bootMount configurationLimit;
|
grubSplashImage bootMount configurationLimit;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
@ -112,11 +122,18 @@ in
|
||||||
# ../system/system-options.nix
|
# ../system/system-options.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
system = {
|
system = mkIf config.boot.loader.grub.enable {
|
||||||
build = {
|
build = {
|
||||||
inherit grubMenuBuilder;
|
menuBuilder = grubMenuBuilder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Common attribute for boot loaders so only one of them can be
|
||||||
|
# set at once
|
||||||
|
boot.loader.id = "grub";
|
||||||
|
boot.loader.kernelFile = "vmlinuz";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
environment.extraPackages = mkIf config.boot.loader.grub.enable [ pkgs.grub ];
|
||||||
|
|
||||||
# and many other things that have to be moved inside this file.
|
# and many other things that have to be moved inside this file.
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
./hardware/network/rt73.nix
|
./hardware/network/rt73.nix
|
||||||
./hardware/pcmcia.nix
|
./hardware/pcmcia.nix
|
||||||
./installer/grub/grub.nix
|
./installer/grub/grub.nix
|
||||||
|
./installer/generations-dir/generations-dir.nix
|
||||||
./installer/tools/nixos-checkout.nix
|
./installer/tools/nixos-checkout.nix
|
||||||
./installer/tools/tools.nix
|
./installer/tools/tools.nix
|
||||||
./misc/assertions.nix
|
./misc/assertions.nix
|
||||||
|
|
|
@ -22,14 +22,20 @@ EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$action" = "switch" -o "$action" = "boot"; then
|
if test "$action" = "switch" -o "$action" = "boot"; then
|
||||||
if test -n "@grubDevice@"; then
|
if [ "@bootLoader@" == "grub" ]; then
|
||||||
mkdir -m 0700 -p /boot/grub
|
if test -n "@grubDevice@"; then
|
||||||
@grubMenuBuilder@ @out@
|
mkdir -m 0700 -p /boot/grub
|
||||||
if test "$NIXOS_INSTALL_GRUB" = 1; then
|
@menuBuilder@ @out@
|
||||||
@grub@/sbin/grub-install "@grubDevice@" --no-floppy --recheck
|
if test "$NIXOS_INSTALL_GRUB" = 1; then
|
||||||
fi
|
@grub@/sbin/grub-install "@grubDevice@" --no-floppy --recheck
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Warning: don't know how to make this configuration bootable; please set \`boot.grubDevice'." 1>&2
|
||||||
|
fi
|
||||||
|
elif [ "@bootLoader@" == "generationsDir" ]; then
|
||||||
|
@menuBuilder@ @out@
|
||||||
else
|
else
|
||||||
echo "Warning: don't know how to make this configuration bootable; please set \`boot.grubDevice'." 1>&2
|
echo "Warning: don't know how to make this configuration bootable; please enable a boot loader." 1>&2
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,20 @@ let
|
||||||
Additional configurations to build.
|
Additional configurations to build.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.boot.loader.id = pkgs.lib.mkOption {
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Id string of the used bootloader.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.boot.loader.kernelFile = pkgs.lib.mkOption {
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Name of the kernel file to be passed to the bootloader.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,13 +47,17 @@ let
|
||||||
|
|
||||||
|
|
||||||
systemBuilder = let
|
systemBuilder = let
|
||||||
kernelfile = if (pkgs.stdenv.system == "armv5tel-linux")
|
kernelPath = "${config.boot.kernelPackages.kernel}/" +
|
||||||
then "${config.boot.kernelPackages.kernel}/uImage"
|
"${config.system.boot.loader.kernelFile}";
|
||||||
else "${config.boot.kernelPackages.kernel}/vmlinuz";
|
in
|
||||||
in ''
|
''
|
||||||
ensureDir $out
|
ensureDir $out
|
||||||
|
|
||||||
ln -s ${kernelfile} $out/kernel
|
if [ ! -f ${kernelPath} ]; then
|
||||||
|
echo "The bootloader cannot find the proper kernel image."
|
||||||
|
echo "(Expecting ${kernelPath})"
|
||||||
|
fi
|
||||||
|
ln -s ${kernelPath} $out/kernel
|
||||||
if [ -n "$grub" ]; then
|
if [ -n "$grub" ]; then
|
||||||
ln -s $grub $out/grub
|
ln -s $grub $out/grub
|
||||||
fi
|
fi
|
||||||
|
@ -76,13 +94,9 @@ let
|
||||||
name = "system";
|
name = "system";
|
||||||
buildCommand = systemBuilder;
|
buildCommand = systemBuilder;
|
||||||
inherit children;
|
inherit children;
|
||||||
grub = if (pkgs.stdenv.system != "armv5tel-linux") then pkgs.grub
|
|
||||||
else null;
|
|
||||||
grubDevice = config.boot.grubDevice;
|
|
||||||
kernelParams =
|
kernelParams =
|
||||||
config.boot.kernelParams ++ config.boot.extraKernelParams;
|
config.boot.kernelParams ++ config.boot.extraKernelParams;
|
||||||
grubMenuBuilder = config.system.build.grubMenuBuilder;
|
menuBuilder = config.system.build.menuBuilder;
|
||||||
configurationName = config.boot.configurationName;
|
|
||||||
# Most of these are needed by grub-install.
|
# Most of these are needed by grub-install.
|
||||||
path = [
|
path = [
|
||||||
pkgs.coreutils
|
pkgs.coreutils
|
||||||
|
@ -92,6 +106,12 @@ let
|
||||||
pkgs.diffutils
|
pkgs.diffutils
|
||||||
pkgs.upstart # for initctl
|
pkgs.upstart # for initctl
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Boot loaders
|
||||||
|
bootLoader = config.system.boot.loader.id;
|
||||||
|
grub = if config.boot.loader.grub.enable then pkgs.grub else null;
|
||||||
|
grubDevice = config.boot.loader.grub.grubDevice;
|
||||||
|
configurationName = config.boot.loader.grub.configurationName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue