T490 + Windows 11 dual-boot: review branch t490-dualboot #1
Labels
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: sscoble/laptop-config#1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
This branch adds support for installing NixOS alongside an existing Windows 11 install on the ThinkPad T490 20N3, sharing the existing EFI System Partition (no separate ESP needed).
Changes
modules/laptop.nix— Bootloader config now declares an explicitboot.loader.systemd-boot.extraEntriesfor "Windows Boot Manager", chainloading the standard Microsoft EFI binary at$ESP/EFI/Microsoft/Boot/bootmgfw.efi. Sort keyz_windowsplaces it after the NixOS generation entries.configurationLimitraised from default to 50 to keep more generations in the menu. NixOS 26.05 ("Yarara") may also autodetect Windows on a shared ESP, in which case the explicit entry is a harmless duplicate.install.sh(new, executable) — Guided dual-boot installer that can be curl-piped from the NixOS installer ISO:Auto-detects the T490's internal NVMe (
/dev/nvme0n1), finds the existing ESP and Windows NTFS partition, shrinks Windows withntfsresize(no data loss), creates a NixOS ext4 root partition, mounts the existing ESP at/mnt/boot, and runsnixos-installwith this flake. Idempotent except for the partition shrink (which only happens once). Override defaults with env vars:DISK,NIXOS_SIZE,SWAP_SIZE,FLAKE_URL,HOST.MIGRATION.md— New "T490 + Windows 11 dual-boot" section at the top of the doc, with the guided flow, manual fallback for unusual layouts, and NixOS 26.05 compatibility notes (systemd Stage 1 initrd default,boot.supportedFilesystemsattrset,systemd.extraConfigremoved — none of which affect this config).Tested
nix flake check— boot config evaluates correctly. TheextraEntriesproduces exactly the expected systemd-boot conf content:install.sh— Reviewed for shell correctness; partition identification switched from glob expansion tolsblkenumeration (the original${DISK}p?glob breaks on disks with >9 partitions).ntfsresizecall now uses correct--size <bytes>syntax with a unit-aware byte conversion. Not yet run on real hardware — the T490 still has Win11, no NixOS install yet.NixOS 26.05 "Yarara" notes
The flake pins
nixos-unstable, which as of June 2026 tracks 26.05+. Key 26.05 changes verified not to break this config:boot.initrd.systemd.enableis default true → no action neededboot.supportedFilesystemsis now attrset, not list → no impact (we don't override it)systemd.extraConfigremoved → no impact (we don't use it)boot.loader.systemd-boot.windowsoption exists for multi-drive setups → not needed for shared-ESP T490Decisions that need review
systemd-boot vs GRUB: stayed with systemd-boot (the existing choice) rather than switching to GRUB with
os-prober. Pro: minimal change, fewer moving parts, matches the rest of the repo. Con: manual entry instead of auto-detection. Easy to flip later if needed.The
install.shscript's ntfsresize step: requires that Windows has been shut down cleanly (or the user has runchkdsk /ffrom WinRE). If Windows was force-shut, the script will refuse to shrink. Worth documenting in the README.Branch name:
t490-dualboot. If you want it named differently, rename before merge.What I can't do from here
Links
t490-dualboot(pushed)921fc14Branch review —
t490-dualboot(commit921fc14)Verdict: findings (correctness bugs in
install.sh). Three real bugs found in the new partition-creation logic. All three have been fixed and committed on the same branch as060194b install.sh: fix swap creation and partition-range bugs(pushed tot490-dualboot). The other changes (modules/laptop.nixextraEntries,MIGRATION.md) look correct.Findings
1.
install.sh—parted mkpartrange would overlap the recovery partition (BLOCKING)install.sh:146was:That asks parted for a range
[disk_size - NIXOS_SIZE, disk_size]. On a stock T490 the recovery partition sits at the end of the disk, so this range overlaps the recovery partition andpartedwill refuse. The script's intent was to fill the space freed by thentfsresizeshrink (which is in the middle of the disk, after the shrunken Windows partition), not the tail of the disk.Fix applied in
060194b: compute the start of the freed space as the new end of the (now shrunken) Windows partition, in 1 MiB units, and pass that as the explicit start toparted mkpart. The new partition now lands exactly where the shrink freed space.2.
install.sh— swap partition is advertised but never created (BLOCKING)The "Plan" block at
install.sh:100-106tells the user:…but no swap partition is ever created and
swaponis never called. The defaultSWAP_SIZE=16Gmeans a user running the script out-of-the-box would have a 16 GB phantom partition the menu claims exists.Fix applied in
060194b: add a secondparted mkpart primary linux-swapafter the NixOS root, runmkswap+swapon. The total shrink applied to the Windows partition is nowNIXOS_SIZE + SWAP_SIZE(so the swap actually fits on disk).3.
install.sh—sort | tail -1partition discovery is fragile (MEDIUM)install.sh:151picked the new partition aslsblk ... | sort | tail -1. That works for the common T490 case (3–5 existing partitions, one new one) but breaks as soon as more than one new partition is created (post-fix, that's NixOS root + swap) and is also fragile for disks with 10+ existing partitions — which the body of the ticket already flagged as the${DISK}p?glob pitfall.Fix applied in
060194b: snapshot the partition list beforemkpart, then usecomm -13to diff the post-mkpartlist and pick the new entries deterministically.What I did NOT change
modules/laptop.nixextraEntries(windows.conf) — Format is correct. The BLS-spec keys (title,efi,sort-key,type oneshot) all match the upstream Boot Loader Spec and current systemd-boot. The''…''raw string does produce a leading blank line in the conf, but systemd-boot is tolerant and this is purely cosmetic.ntfsresize --sizesyntax — Correct.--sizeis byte count,-sperforms the shrink. The unit-aware byte conversion is right (I refactored it into a smallsize_to_byteshelper for clarity, that's the only change in that area).install.sh: the script already fails cleanly when no ESP is found (install.sh:92) or no Windows NTFS partition is found (install.sh:93). I left these messages intact.MIGRATION.md26.05 notes — Plausible forward-looking notes aboutboot.initrd.systemd.enable,boot.supportedFilesystemsas attrset, andsystemd.extraConfigremoval. None of these are exercised by the current config so they're no-ops. Caveat: I could not independently verify the 26.05 specifics from this environment (nixpkgs-unstable in June 2026 may or may not track 26.05+). Worth a quick eyeball when Scott first builds on the device. The MIGRATION.md step 4 already flags this as "expected" rather than "verified," which is honest.Decisions-that-need-review responses
extraEntriesis the right call for a shared-ESP T490; GRUB + os-prober is a bigger change with more moving parts. Easy to flip later if needed.ntfsresizerequires clean shutdown of Windows — APPROVE (with a suggestion). The currentntfsfix -dstep is exactly the right auto-recovery for the forced-shutdown case, but the user-facinginstall.shdoesn't surface this requirement. Suggestion: add a one-linewarn "If you forced-shut Windows, reboot into Windows and run 'chkdsk /f' first — the script will otherwise refuse to shrink."before thentfsfix -dcall. Not blocking, but worth a follow-up commit.t490-dualboot— APPROVE (no rename needed for review).Open questions for Scott
ntfsresize, or is the MIGRATION.md already the canonical "read this first" doc? (I left the script as-is to keep this commit scoped to the three correctness bugs.)nixos-unstablein June 2026 actually tracks 26.05+. If not, the MIGRATION.md section "NixOS 26.05 ('Yarara') compatibility" should be retitled or removed.Artifacts
t490-dualboot:060194b(060194b install.sh: fix swap creation and partition-range bugs)main; pushed toorigin/t490-dualbootmodules/laptop.nixandMIGRATION.mdunchanged from the original921fc14