Files

100 lines
4.8 KiB
Nix
Raw Permalink Normal View History

2026-08-05 20:23:33 +01:00
{
self,
inputs,
...
}: {
flake.nixosModules.shadowConfiguration = {...}: {
networking = {
hostName = "shadow";
};
# Windows lives on the 476G NVMe -- the one with three partitions: 16M
# "Microsoft reserved" MSR, 476G NTFS (fs-uuid 70E4E841E4E80AE4, the C:
# volume), 832M WinRE. Identified by layout rather than by nvmeXnY on
# purpose; see the enumeration note below.
#
# That disk has NO EFI System Partition of its own -- its 16M partition is a
# "Microsoft reserved" MSR with no filesystem. Windows was installed against
# the ESP that NixOS now owns: the 1G vfat partition fs-uuid 5873-AD05 on the
# 1.9T NVMe (that disk holds only two partitions, the ESP and the ext4 root
# deff63fc-1738-4cfc-a79c-06e58c78471a). So both OSes boot from one shared
# ESP; there is no separate Windows boot drive.
#
# The NixOS install reformatted that ESP, which wiped
# EFI/Microsoft/Boot/{bootmgfw.efi,BCD} and left Windows unbootable. That has
# since been repaired from WinRE and both files are back in place, so the
# menuentry below is live. Keep the recovery command to hand in case the ESP
# is ever reformatted again -- it has to be run from Windows install media or
# WinRE, because the BCD store cannot be generated from Linux:
#
# bcdboot C:\Windows /s S: /f UEFI (S: = the ESP, fs-uuid 5873-AD05)
#
# Copying bootmgfw.efi alone is not enough; without BCD it fails 0xc000000f.
# Note bcdboot also drops a copy of the Windows boot manager at
# EFI/BOOT/bootx64.efi -- see the fallback-path note in core/boot.nix.
#
# Chainloaded explicitly rather than via grub.useOSProber: deterministic,
# pulls in no extra tooling, and avoids probing every disk on each bootloader
# install. The `-f` guard makes the entry self-disabling: it renders only
# while bootmgfw.efi is actually present, so a future ESP reformat degrades
# to a missing menu item rather than one that boots into an error.
#
# fs-uuid is shadow's ESP, matching the "/boot" entry in disks.nix. Searching
# by UUID rather than (hdX,gptN) matters here: NVMe enumeration is not stable
# on this board -- /boot has been seen as both nvme0n1p1 and nvme1n1p1. For
# the same reason, re-derive device names before running anything
# destructive:
#
# lsblk -o NAME,SIZE,FSTYPE,PARTTYPENAME,UUID,MOUNTPOINT
#
# Windows' boot files now occupy ~30-60MiB of that shared 1G ESP and Windows
# Update rewrites them periodically, which is part of why
# grub.configurationLimit is held at 10 in core/boot.nix.
#
# Before dual-booting, turn off Windows Fast Startup. hiberfil.sys is present
# on the 476G NTFS volume, and Fast Startup plus this host's hibernation
# setup will corrupt any NTFS volume mounted read-write from both sides.
#
# On the GRUB script itself:
#
# The outer `search` + `-f` test run at *boot*, while GRUB parses grub.cfg —
# not at Nix eval time. That is why repairing Windows needed no rebuild: the
# entry started rendering as soon as bcdboot put bootmgfw.efi back, and it
# will stop again by itself if the file disappears.
#
# The `-n "$esp"` test is a *separate,
# nested* if rather than `[ -n "$esp" -a -f ... ]`: a failed search leaves
# $esp unset, and GRUB's `test` builtin evaluates both operands of `-a`
# rather than short-circuiting, so the combined form would still expand the
# `-f` to `()/...` and could complain about a bad device on every boot.
# Nesting guarantees the path test is not reached at all.
#
# No `insmod` is needed for the outer search: GRUB's EFI core image already
# embeds part_gpt/fat/search_fs_uuid, since it must find its own $prefix on
# the FAT ESP before reading this file. NixOS' own install-grub.pl relies on
# exactly that for the search it emits. The insmods inside the menuentry are
# kept only because `chain` genuinely is a separate module.
#
# The inner `search` deliberately repeats the outer one rather than reusing
# `set root=$esp`. It costs one extra disk scan, and only when the entry is
# actually selected, in exchange for a menuentry that is self-contained and
# cannot be broken by anything that clobbers $esp in between. This also
# matches the per-entry search install-grub.pl generates.
boot.loader.grub.extraEntries = ''
search --no-floppy --set=esp --fs-uuid 5873-AD05
if [ -n "$esp" ]; then
if [ -f ($esp)/EFI/Microsoft/Boot/bootmgfw.efi ]; then
menuentry "Windows Boot Manager" --class windows --class os {
insmod part_gpt
insmod fat
insmod chain
search --no-floppy --set=root --fs-uuid 5873-AD05
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
fi
fi
'';
2026-08-05 20:23:33 +01:00
};
}