Dual Booting NixOS and Windows
This section explains various methods to have the bootloader prompt whether to boot windows or NixOS.
Autodetection
systemd-boot
When systemd-boot
is installed to the same EFI System Partition (ESP) that Windows uses, it will automatically detect the Windows installation (/EFI/Microsoft/Boot/bootmgfw.efi
) and present it as a boot option.
You can verify detected boot loaders by running the bootctl
command.
A system pre-installed with Windows might have a small ESP partition size that is not sufficient to store the kernel and initrd files for multiple NixOS generations. One solution is to create an additional XBOOTLDR partition and configure systemd-boot
to use it:
/etc/nixos/configuration.nix
{
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/57D4-A2B2";
fsType = "vfat";
};
fileSystems."/efi" =
{ device = "/dev/disk/by-uuid/3280-5418";
fsType = "vfat";
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.efi.efiSysMountPoint = "/efi";
boot.loader.systemd-boot.xbootldrMountPoint = "/boot";
}
os-prober
os-prober
is a tool to autodetect which other systems are present on the machine. Grub can be
told to use os-prober to add a menu-entry for each of them.
/etc/nixos/configuration.nix
{ config, pkgs, ... }: {
# ...
boot.loader.grub.enable = true;
boot.loader.grub.device = "nodev";
boot.loader.grub.useOSProber = true;
# ...
}
Manual configuration
In case os-prober
does not detect your windows partition you can configure your bootloader manually to find it.
MBR
All MBR bootloaders will need at least some configuration to chainload Windows.
Grub
Here is an example config:
/etc/nixos/configuration.nix
{ config, pkgs, ... }: {
# ...
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
boot.loader.grub.extraEntries = ''
menuentry "Windows 7" {
chainloader (hd0,1)+1
}
'';
}
Source: https://www.reddit.com/r/NixOS/comments/31lx3i/windows_and_nixos_dual_boot/
UEFI
After setting up a 256mb EFI Partition dualboot should work out of the box (at least for windows10)
Source: https://zimbatm.com/journal/2016/09/09/nixos-window-dual-boot/ (Archive.org Mirror)
Here is another article that documents dual booting NixOS and Windows on a Lenovo ThinkPad X1 Carbon (6th Gen): https://github.com/andywhite37/nixos/blob/master/DUAL_BOOT_WINDOWS_GUIDE.md
Grub
Here we assume:
- the EFI partition has been mounted on /boot/efi
$FS_UUID
is the UUID of the EFI partition- the
boot.loader.systemd-boot.enable = true;
line added to configuration.nix bynixos-generate-config
has been removed
/etc/nixos/configuration.nix
{ config, ... }:
{
boot.loader = {
efi = {
canTouchEfiVariables = true;
# assuming /boot is the mount point of the EFI partition in NixOS (as the installation section recommends).
efiSysMountPoint = "/boot";
};
grub = {
# despite what the configuration.nix manpage seems to indicate,
# as of release 17.09, setting device to "nodev" will still call
# `grub-install` if efiSupport is true
# (the devices list is not used by the EFI grub install,
# but must be set to some value in order to pass an assert in grub.nix)
devices = [ "nodev" ];
efiSupport = true;
enable = true;
# set $FS_UUID to the UUID of the EFI partition
extraEntries = ''
menuentry "Windows" {
insmod part_gpt
insmod fat
insmod search_fs_uuid
insmod chain
search --fs-uuid --set=root $FS_UUID
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
'';
version = 2;
};
};
}
EFI with multiple disks
When Windows is installed on another disk with a separate EFI partition, the following might work:
/etc/nixos/configuration.nix
{ config, ... }:
{
boot.loader = {
efi.canTouchEfiVariables = true;
grub = {
enable = true;
devices = [ "nodev" ];
efiSupport = true;
useOSProber = true;
};
};
}
System time
System clock might be incorrect after booting Windows and going back to the NixOS. It can be fixed by either setting RTC time standard to UTC on Windows, or setting it to localtime on NixOS.
Setting RTC time standard to localtime, compatible with Windows in its default configuration:
/etc/nixos/configuration.nix
{
time.hardwareClockInLocalTime = true;
}
See also
- Arch Linux wiki#GRUB
- NixOS GRUB installer (check the code block beginning with # install EFI GRUB)