* Lots of refactoring; put the CD image generation in rescue-cd.nix.

Support booting from something other than a CD.  Add some parameters
  to specify the root device.

svn path=/nixu/trunk/; revision=7000
This commit is contained in:
Eelco Dolstra 2006-11-12 18:48:47 +00:00
parent afc05314c4
commit 0785dfb9f8
4 changed files with 122 additions and 73 deletions

View file

@ -6,11 +6,13 @@ fail() {
exec @shell@
}
# Print a greeting.
echo
echo "<<< NixOS Stage 1 >>>"
echo
# Set the PATH.
export PATH=/empty
for i in @path@; do
@ -20,6 +22,7 @@ for i in @path@; do
fi
done
# Mount special file systems.
mkdir /etc # to shut up mount
touch /etc/fstab # idem
@ -28,52 +31,68 @@ mount -t proc none /proc
mkdir /sys
mount -t sysfs none /sys
# Create device nodes in /dev.
source @makeDevices@
# Load some kernel modules.
export MODULE_DIR=@modules@/lib/modules/
modprobe ide-generic
modprobe ide-disk
modprobe ide-cd
# Try to find and mount the installation CD.
# Mount the installation CD.
# Try to find and mount the root device.
mkdir /mnt
mkdir /mnt/cdrom
mkdir /mnt/root
echo "probing for the NixOS installation CD..."
echo "mounting the root device..."
for i in /sys/devices/*/*/media; do
if test "$(cat $i)" = "cdrom"; then
if test -n "@autoDetectRootDevice@"; then
# Hopefully `drivename' matches the device created in /dev.
devName=/dev/$(cat $(dirname $i)/drivename)
# Look for the root device by label.
echo "probing for the NixOS installation CD..."
echo " in $devName..."
for i in /sys/devices/*/*/media; do
if test "$(cat $i)" = "cdrom"; then
if mount -o ro -t iso9660 $devName /mnt/cdrom; then
if test -e "/mnt/cdrom/@cdromLabel@"; then
found=1
break
# Hopefully `drivename' matches the device created in /dev.
devName=/dev/$(cat $(dirname $i)/drivename)
echo " in $devName..."
if mount -o ro -t iso9660 $devName /mnt/root; then
if test -e "/mnt/root/@rootLabel@"; then
found=1
break
fi
umount /mnt/root
fi
umount /mnt/cdrom
fi
fi
done
fi
done
if test -z "$found"; then
echo "CD not found!"
if test -z "$found"; then
echo "CD not found!"
fail
fi
else
# Hard-coded root device.
mount -o ro "@rootDevice@" /mnt/root
# Testing.
fail
fi
# Start stage 2.
# !!! Note: we can't use pivot_root here (the kernel gods have
# decreed), but we could use run-init from klibc, which deletes all
# files in the initramfs, remounts the target root on /, and chroots.
cd /mnt/cdrom
cd /mnt/root
mount --move . /
umount /proc # cleanup
umount /sys

View file

@ -6,13 +6,25 @@
{ genericSubstituter, shell, staticTools
, module_init_tools, extraUtils, modules
, cdromLabel ? ""
, # Whether to find root device automatically using its label.
autoDetectRootDevice
, # If not scanning, the root must be specified explicitly.
rootDevice
# If scanning, we need a disk label.
, rootLabel
}:
assert !autoDetectRootDevice -> rootDevice != "";
assert autoDetectRootDevice -> rootLabel != "";
genericSubstituter {
src = ./boot-stage-1-init.sh;
isExecutable = true;
inherit shell modules cdromLabel;
inherit shell modules;
inherit autoDetectRootDevice rootDevice rootLabel;
path = [
staticTools
module_init_tools

63
test/rescue-cd.nix Normal file
View file

@ -0,0 +1,63 @@
let
# The label used to identify the installation CD.
cdromLabel = "NIXOS";
in
# Build boot scripts for the CD that find the CD-ROM automatically.
with import ./rescue-system.nix {
autoDetectRootDevice = true;
rootLabel = cdromLabel;
};
rec {
# Since the CD is read-only, the mount points must be on disk.
cdMountPoints = pkgs.stdenv.mkDerivation {
name = "mount-points";
builder = builtins.toFile "builder.sh" "
source $stdenv/setup
mkdir $out
cd $out
mkdir proc sys tmp etc dev var mnt nix nix/var
touch $out/${cdromLabel}
";
};
# Create an ISO image containing the isolinux boot loader, the
# kernel, the initrd produced above, and the closure of the stage 2
# init.
rescueCD = import ./make-iso9660-image.nix {
inherit (pkgs) stdenv cdrtools;
isoName = "nixos.iso";
contents = [
{ source = pkgs.syslinux + "/lib/syslinux/isolinux.bin";
target = "isolinux/isolinux.bin";
}
{ source = ./isolinux.cfg;
target = "isolinux/isolinux.cfg";
}
{ source = pkgs.kernel + "/vmlinuz";
target = "isolinux/vmlinuz";
}
{ source = initialRamdisk + "/initrd";
target = "isolinux/initrd";
}
{ source = cdMountPoints;
target = "/";
}
];
init = bootStage2;
bootable = true;
bootImage = "isolinux/isolinux.bin";
};
}

View file

@ -1,4 +1,8 @@
{system ? __currentSystem}:
{ system ? __currentSystem
, autoDetectRootDevice ? false
, rootDevice ? ""
, rootLabel ? ""
}:
rec {
@ -20,10 +24,6 @@ rec {
};
# The label used to identify the installation CD.
cdromLabel = "NIXOS";
# Determine the set of modules that we need to mount the root FS.
modulesClosure = import ./modules-closure.nix {
inherit (pkgs) stdenv kernel module_init_tools;
@ -49,7 +49,7 @@ rec {
inherit (pkgs) genericSubstituter;
inherit (pkgsDiet) module_init_tools;
inherit extraUtils;
inherit cdromLabel;
inherit autoDetectRootDevice rootDevice rootLabel;
modules = modulesClosure;
shell = stdenvLinuxStuff.bootstrapTools.bash;
staticTools = stdenvLinuxStuff.staticTools;
@ -113,49 +113,4 @@ rec {
};
# Since the CD is read-only, the mount points must be on disk.
cdMountPoints = pkgs.stdenv.mkDerivation {
name = "mount-points";
builder = builtins.toFile "builder.sh" "
source $stdenv/setup
mkdir $out
cd $out
mkdir proc sys tmp etc dev var mnt nix nix/var
touch $out/${cdromLabel}
";
};
# Create an ISO image containing the isolinux boot loader, the
# kernel, the initrd produced above, and the closure of the stage 2
# init.
rescueCD = import ./make-iso9660-image.nix {
inherit (pkgs) stdenv cdrtools;
isoName = "nixos.iso";
contents = [
{ source = pkgs.syslinux + "/lib/syslinux/isolinux.bin";
target = "isolinux/isolinux.bin";
}
{ source = ./isolinux.cfg;
target = "isolinux/isolinux.cfg";
}
{ source = pkgs.kernel + "/vmlinuz";
target = "isolinux/vmlinuz";
}
{ source = initialRamdisk + "/initrd";
target = "isolinux/initrd";
}
{ source = cdMountPoints;
target = "/";
}
];
init = bootStage2;
bootable = true;
bootImage = "isolinux/isolinux.bin";
};
}