Skip to content

Commit

Permalink
UEFI support
Browse files Browse the repository at this point in the history
  • Loading branch information
Rotsor committed Feb 19, 2017
1 parent ad50c3f commit 2c4b423
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 19 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/latest-iso-minimal-x86_64-linux
/latest-iso-graphical-x86_64-linux
/nixos-in-place-test
*.iso
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ old system and all your old files still exist and are setup to mount on
`/old-root/nixos` and `/` is rebound before spinning up the system; everything
else in `/old-root` is fair game to delete.

NixOS installs GRUB2 on top of your existing boot loader. If you'd like to boot
into `/old-root`, you can; you just need to add the GRUB entry, from
If your system boots using MBR, NixOS installs GRUB2 on top of your existing boot loader.
If you'd like to boot into `/old-root`, you can; you just need to add the GRUB entry, from
`/old-root/boot/grub`, manually in your Nix files.

If your system boots using UEFI, NixOS adds systemd-boot efi image to your
efi system partition, so your bios should let you choose between your old efi
image and systemd-boot.

## Platform-specifics
### Digital Ocean
For use on DO droplets, follow the normal steps for your platform (Debian has
Expand Down
60 changes: 50 additions & 10 deletions install
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,46 @@ check_existence "grep"
check_existence "unsquashfs"
check_existence "mktemp"
check_existence "id"
check_existence "head"
check_existence "tail"
check_existence "fdisk"
check_existence "cat"
log_end "seems sane"

## Setup essential variables; allow overriding with input
root_mount=$(mount | grep "/ " | sed 's/ /\n/' | head -n1)
root_type=$(mount | grep -Eo "/ type \w+" | sed 's/ /\n/g' | tail -n1)
if grep '/dev/nvme' <<< $root_mount; then
grub_device=$(echo $root_mount | sed "s|p[0-9]\+$||");
elif grep '/dev/sd' <<< $root_mount; then
grub_device=$(echo $root_mount | sed "s|[0-9]\+||");
elif grep '/dev/vd' <<< $root_mount; then
grub_device=$(echo $root_mount | sed "s|[0-9]\+||");

expect_one_line() {
ERROR_MESSAGE_ZERO=$1
ERROR_MESSAGE_MULTIPLE=$2
(set -eu;
IFS='' read -r x || (echo "$ERROR_MESSAGE_ZERO" >& 2; exit 1)
(! IFS='' read -r) || (echo "$ERROR_MESSAGE_MULTIPLE" >& 2; exit 1)
printf "%s\n" "$x");
}

if [ -d /sys/firmware/efi ]; then
boot_type=uefi
boot_device=$(
set -euo pipefail
fdisk -l -o 'Device,Type' |
grep 'EFI System' |
sed -r 's_([^ ]*) *EFI System$_\1_' |
expect_one_line \
"Fdisk found no EFI System Partitions: please specify with -g option" \
"Found multiple EFI System Partitions: please specify with -g option")
else
echo "Unable to determine your grub boot device! Please specify with the -g option."
boot_type=mbr
if grep '/dev/nvme' <<< "$root_mount"; then
boot_device=$(echo "$root_mount" | sed "s|p[0-9]\+$||");
elif grep '/dev/sd' <<< "$root_mount"; then
boot_device=$(echo "$root_mount" | sed "s|[0-9]\+||");
elif grep '/dev/vd' <<< "$root_mount"; then
boot_device=$(echo "$root_mount" | sed "s|[0-9]\+||");
else
echo "Unable to determine your grub boot device! Please specify with the -g option."
fi
fi
working_directory=$(mktemp -d)

Expand All @@ -48,7 +75,7 @@ digitalocean=false
while getopts ":g:r:t:Gdw:h" opt; do
case $opt in
g)
grub_device=$OPTARG
boot_device=$OPTARG
;;
r)
root_mount=$OPTARG
Expand Down Expand Up @@ -100,9 +127,22 @@ then
fi
fi

boot_description=$(
case $boot_type in
uefi)
echo "uefi boot with esp at $boot_device"
;;
mbr)
echo "mbr at $boot_device"
;;
*)
echo "bad boot type" >&2
exit 1
;;
esac)
## Give one last chance to back out
log "NixOS installer (nixos-in-place)"
log " GRUB => $grub_device"
log " Boot => $boot_description"
log " Root => $root_mount ($root_type)"
log " ISO => $iso"
log " Digital Ocean => $digitalocean"
Expand Down Expand Up @@ -134,7 +174,7 @@ pushd "$working_directory"
## Setup the chroot environment before install
log "Embarking stage1!"
"$here/stage1" "$here" "$root_mount" "$root_type" "$grub_device" "$digitalocean"
"$here/stage1" "$here" "$root_mount" "$root_type" "$boot_type" "$boot_device" "$digitalocean"
## Minimize residual space usage
# /var/empty is immutable https://github.com/NixOS/nixpkgs/pull/18365
Expand Down
22 changes: 19 additions & 3 deletions stage1
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ set -eu
here=$1
root_mount=$2
root_type=$3
grub_device=$4
digitalocean=$5
boot_type=$4
boot_device=$5
digitalocean=$6

## Bring in some helper functions
. "$here/util"
Expand All @@ -28,7 +29,7 @@ log_end "$BASH"

## Don't run systemd on chroot start, run our stage2 script
log "Patching init"
sed -i "s,exec systemd,exec /$BASH -i /nixos-in-place/stage2 $root_mount $root_type $grub_device $digitalocean," "$INIT"
sed -i "s,exec systemd,exec /$BASH -i /nixos-in-place/stage2 $root_mount $root_type $boot_type $boot_device $digitalocean," "$INIT"
sed -i "s,starting systemd,starting /nixos-in-place/stage2," "$INIT"

## Don't try to remount / since we didn't do a proper phase 1
Expand All @@ -43,12 +44,27 @@ mount --bind /nixos nixos
mkdir -p nixos-in-place
mount --bind "$here" nixos-in-place

case "$boot_type" in
mbr)
true
;;
uefi)
(ls -1 /sys/firmware/efi/efivars | grep -q .) || mount -t efivarfs efivarfs /sys/firmware/efi/efivars
mkdir -p nixos/boot
mount "$boot_device" nixos/boot
;;
*)
echo "bad boot type" >&2
exit 1
esac

## Imbue the modified live CD environment so we can install
log "Embarking stage2!"
chroot . "/$INIT"

## Various platforms use different flags; just try what we can to clean up
log "Cleaning up mounts"
umount -f nixos/boot >/dev/null 2>&1 || true
umount -fR nixos >/dev/null 2>&1 || true
umount -f nixos >/dev/null 2>&1 || true
umount -f nixos-in-place >/dev/null 2>&1 || true
Expand Down
21 changes: 18 additions & 3 deletions stage2
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ set -eu

root_mount=$1
root_type=$2
grub_device=$3
digitalocean=$4
boot_type=$3
boot_device=$4
digitalocean=$5
digitalocean_configs=""

if [ "$digitalocean" = "true" ];
Expand Down Expand Up @@ -47,12 +48,26 @@ nix-env -i pcre
## Generate a base config
nixos-generate-config --root /nixos

grub_device_config=$(
case "$boot_type" in
mbr)
echo "boot.loader.grub.device = \"$boot_device\";\n"
;;
uefi)
true
;;
*)
echo "bad boot type" >&2
exit 1
;;
esac)
cat <<EOF > /nixos/etc/nixos/nixos-in-place.nix
{ config, pkgs, ... }:
{
## Everything below is generated from nixos-in-place; modify with caution!
boot.kernelParams = ["boot.shell_on_fail"];
boot.loader.grub.device = "$grub_device";
$grub_device_config
boot.loader.grub.storePath = "/nixos/nix/store";
boot.initrd.supportedFilesystems = [ "$root_type" ];
boot.initrd.postDeviceCommands = ''
Expand Down
2 changes: 1 addition & 1 deletion util
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ show_help()
log "usage: $0 [OPTION...]"
log
log " -h Show this help message"
log " -g <dev> Set GRUB target device (default: ${grub_device:-undefined})"
log " -g <dev> Set boot device (a device with MBR or EFI System Partition) (default: ${boot_device:-undefined})"
log " -r <dev> Set root filesystem target device (default: ${root_mount:-undefined})"
log " -t <type> Set root filesystem type (default: ${root_type:-undefined})"
log " -G Use the graphical NixOS ISO (default: ${iso:-undefined})"
Expand Down

0 comments on commit 2c4b423

Please sign in to comment.