3
0
Fork 0
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:
Lluís Batlle i Rossell 2009-09-27 21:51:37 +00:00
parent 852478ff79
commit 75f6cd20da
7 changed files with 303 additions and 94 deletions

View file

@ -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;

View 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

View 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";
};
}

View file

@ -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.
} }

View 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

View file

@ -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

View file

@ -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;
}; };