* 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:
parent
afc05314c4
commit
0785dfb9f8
|
@ -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
|
||||
done
|
||||
|
||||
if test -z "$found"; then
|
||||
echo "CD not found!"
|
||||
fail
|
||||
fi
|
||||
done
|
||||
|
||||
if test -z "$found"; then
|
||||
echo "CD not found!"
|
||||
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
|
||||
|
|
|
@ -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
63
test/rescue-cd.nix
Normal 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";
|
||||
};
|
||||
|
||||
|
||||
}
|
|
@ -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";
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue