From fbd5b97d79ffdb7c36fe7d45ae2c20c750783567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Partheym=C3=BCller?= Date: Thu, 11 Feb 2021 13:59:06 +0100 Subject: [PATCH 1/7] Split install.wim before creating USB image With newer Windows 10 versions, `install.wim` can become larger than 4GiB, which can't be placed in a FAT32 partition anymore. By splitting it into chunks with `wimsplit` and removing `install.wim`, the larger images work fine. --- wfvm/win.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wfvm/win.nix b/wfvm/win.nix index 395ee8c..0a3193c 100644 --- a/wfvm/win.nix +++ b/wfvm/win.nix @@ -96,7 +96,7 @@ let '' #!${pkgs.runtimeShell} set -euxo pipefail - export PATH=${lib.makeBinPath [ p7zip utils.qemu libguestfs ]}:$PATH + export PATH=${lib.makeBinPath [ p7zip utils.qemu libguestfs pkgs.wimlib ]}:$PATH # Create a bootable "USB" image # Booting in USB mode circumvents the "press any key to boot from cdrom" prompt @@ -106,6 +106,10 @@ let mkdir -p win/nix-win 7z x -y ${windowsIso} -owin + # Split image so it fits in FAT32 partition + wimsplit win/sources/install.wim win/sources/install.swm 3072 + rm win/sources/install.wim + cp ${autounattend.autounattendXML} win/autounattend.xml virt-make-fs --partition --type=fat win/ usbimage.img -- 2.42.0 From 90cc7b14a4cf810317e6422c01037301f9b799ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Partheym=C3=BCller?= Date: Fri, 12 Feb 2021 10:50:21 +0100 Subject: [PATCH 2/7] Use q35 and xHCI for more performance --- wfvm/autounattend.nix | 2 +- wfvm/utils.nix | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/wfvm/autounattend.nix b/wfvm/autounattend.nix index 66744b7..13505eb 100644 --- a/wfvm/autounattend.nix +++ b/wfvm/autounattend.nix @@ -13,7 +13,7 @@ , timeZone ? "UTC" , services ? {} , impureShellCommands ? [] -, driveLetter ? "E:" +, driveLetter ? "D:" , ... }: diff --git a/wfvm/utils.nix b/wfvm/utils.nix index 4084eca..3b42a0a 100644 --- a/wfvm/utils.nix +++ b/wfvm/utils.nix @@ -9,9 +9,10 @@ rec { "-cpu host" "-smp ${cores}" "-m ${qemuMem}" + "-M q35" "-bios ${pkgs.OVMF.fd}/FV/OVMF.fd" "-rtc base=${baseRtc}" - "-device piix3-usb-uhci" + "-device qemu-xhci" "-device e1000,netdev=n1" ] ++ extraFlags; -- 2.42.0 From e8232ab89a5a8903cd9702c180bb027a60ac2e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Partheym=C3=BCller?= Date: Thu, 25 Feb 2021 10:06:54 +0100 Subject: [PATCH 3/7] win: Allow for selection specific image This is useful if the install.wim contains multiple Windows versions (e.g., Home, Pro, ..), because the autounattend file will always select index 1. With this mechanism, a variant different from the first one can be automatically selected. imageSelection can be either an index (1-N) or the image name wiminfo can list all images contained in a given WIM file. The default case is index 1, which has the same effect as before, with the possibility of having a slightly smaller install.wim file because all unwanted variants are discarded. --- wfvm/win.nix | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/wfvm/win.nix b/wfvm/win.nix index 0a3193c..4cc8884 100644 --- a/wfvm/win.nix +++ b/wfvm/win.nix @@ -5,6 +5,8 @@ , impureMode ? false , installCommands ? [] , users ? {} +# autounattend always installs index 1, so this default is backward-compatible +, imageSelection ? "1" , ... }@attrs: @@ -106,10 +108,20 @@ let mkdir -p win/nix-win 7z x -y ${windowsIso} -owin - # Split image so it fits in FAT32 partition - wimsplit win/sources/install.wim win/sources/install.swm 3072 + # Extract desired variant from install.wim + # This is useful if the install.wim contains multiple Windows + # versions (e.g., Home, Pro, ..), because the autounattend file + # will always select index 1. With this mechanism, a variant different + # from the first one can be automatically selected. + # imageSelection can be either an index (1-N) or the image name + # wiminfo can list all images contained in a given WIM file + wimexport win/sources/install.wim "${imageSelection}" win/sources/install_selected.wim rm win/sources/install.wim + # Split image so it fits in FAT32 partition + wimsplit win/sources/install_selected.wim win/sources/install.swm 3072 + rm win/sources/install_selected.wim + cp ${autounattend.autounattendXML} win/autounattend.xml virt-make-fs --partition --type=fat win/ usbimage.img -- 2.42.0 From 1357f493bd68fdc4b2cccb9e49a8ed881341ef96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Partheym=C3=BCller?= Date: Mon, 1 Mar 2021 15:09:55 +0100 Subject: [PATCH 4/7] Add support for legacy installations --- wfvm/autounattend.nix | 11 ++++++----- wfvm/utils.nix | 5 +++-- wfvm/win.nix | 11 ++++++++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/wfvm/autounattend.nix b/wfvm/autounattend.nix index 13505eb..f79df37 100644 --- a/wfvm/autounattend.nix +++ b/wfvm/autounattend.nix @@ -13,7 +13,8 @@ , timeZone ? "UTC" , services ? {} , impureShellCommands ? [] -, driveLetter ? "D:" +, efi ? true +, driveLetter ? if efi then "E:" else "D:" , ... }: @@ -144,12 +145,12 @@ let 1 - EFI - 100 + ${if efi then "EFI" else "Primary"} + 300 2 - MSR + ${if efi then "MSR" else "Primary"} 16 @@ -161,7 +162,7 @@ let 1 - FAT32 + ${if efi then "FAT32" else "NTFS"} 1 diff --git a/wfvm/utils.nix b/wfvm/utils.nix index 3b42a0a..de605ac 100644 --- a/wfvm/utils.nix +++ b/wfvm/utils.nix @@ -1,4 +1,4 @@ -{ pkgs, baseRtc ? "2020-04-20T14:21:42", cores ? "4", qemuMem ? "4G" }: +{ pkgs, baseRtc ? "2020-04-20T14:21:42", cores ? "4", qemuMem ? "4G", efi ? true }: rec { # qemu_test is a smaller closure only building for a single system arch @@ -10,10 +10,11 @@ rec { "-smp ${cores}" "-m ${qemuMem}" "-M q35" - "-bios ${pkgs.OVMF.fd}/FV/OVMF.fd" "-rtc base=${baseRtc}" "-device qemu-xhci" "-device e1000,netdev=n1" + ] ++ pkgs.lib.optionals efi [ + "-bios ${pkgs.OVMF.fd}/FV/OVMF.fd" ] ++ extraFlags; # Pass empty config file to prevent ssh from failing to create ~/.ssh diff --git a/wfvm/win.nix b/wfvm/win.nix index 4cc8884..d189a3e 100644 --- a/wfvm/win.nix +++ b/wfvm/win.nix @@ -7,12 +7,13 @@ , users ? {} # autounattend always installs index 1, so this default is backward-compatible , imageSelection ? "1" +, efi ? true , ... }@attrs: let lib = pkgs.lib; - utils = import ./utils.nix { inherit pkgs; }; + utils = import ./utils.nix { inherit pkgs efi; }; libguestfs = pkgs.libguestfs-with-appliance; # p7zip on >20.03 has known vulns but we have no better option @@ -85,7 +86,7 @@ let "usb-storage,drive=virtio-win" # USB boot "-drive" - "id=win-install,file=usbimage.img,if=none,format=raw,readonly=on" + "id=win-install,file=usbimage.img,if=none,format=raw,readonly=on,media=${if efi then "disk" else "cdrom"}" "-device" "usb-storage,drive=win-install" # Output image @@ -98,7 +99,7 @@ let '' #!${pkgs.runtimeShell} set -euxo pipefail - export PATH=${lib.makeBinPath [ p7zip utils.qemu libguestfs pkgs.wimlib ]}:$PATH + export PATH=${lib.makeBinPath [ p7zip utils.qemu libguestfs pkgs.wimlib pkgs.cdrkit ]}:$PATH # Create a bootable "USB" image # Booting in USB mode circumvents the "press any key to boot from cdrom" prompt @@ -124,7 +125,11 @@ let cp ${autounattend.autounattendXML} win/autounattend.xml + ${if efi then '' virt-make-fs --partition --type=fat win/ usbimage.img + '' else '' + mkisofs -iso-level 4 -l -R -udf -D -b boot/etfsboot.com -no-emul-boot -boot-load-size 8 -hide boot.catalog -eltorito-alt-boot -o usbimage.img win/ + ''} rm -rf win # Qemu requires files to be rw -- 2.42.0 From 84ef1ec7e542d12a923b26a5da11e58107fc64fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Partheym=C3=BCller?= Date: Wed, 10 Mar 2021 11:09:49 +0100 Subject: [PATCH 5/7] win: cdimage naming, closure shrinking --- wfvm/win.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wfvm/win.nix b/wfvm/win.nix index d189a3e..45ffe99 100644 --- a/wfvm/win.nix +++ b/wfvm/win.nix @@ -86,7 +86,7 @@ let "usb-storage,drive=virtio-win" # USB boot "-drive" - "id=win-install,file=usbimage.img,if=none,format=raw,readonly=on,media=${if efi then "disk" else "cdrom"}" + "id=win-install,file=${if efi then "usb" else "cd"}image.img,if=none,format=raw,readonly=on,media=${if efi then "disk" else "cdrom"}" "-device" "usb-storage,drive=win-install" # Output image @@ -99,7 +99,7 @@ let '' #!${pkgs.runtimeShell} set -euxo pipefail - export PATH=${lib.makeBinPath [ p7zip utils.qemu libguestfs pkgs.wimlib pkgs.cdrkit ]}:$PATH + export PATH=${lib.makeBinPath [ p7zip utils.qemu libguestfs pkgs.wimlib ]}:$PATH # Create a bootable "USB" image # Booting in USB mode circumvents the "press any key to boot from cdrom" prompt @@ -128,7 +128,7 @@ let ${if efi then '' virt-make-fs --partition --type=fat win/ usbimage.img '' else '' - mkisofs -iso-level 4 -l -R -udf -D -b boot/etfsboot.com -no-emul-boot -boot-load-size 8 -hide boot.catalog -eltorito-alt-boot -o usbimage.img win/ + ${pkgs.cdrkit}/bin/mkisofs -iso-level 4 -l -R -udf -D -b boot/etfsboot.com -no-emul-boot -boot-load-size 8 -hide boot.catalog -eltorito-alt-boot -o cdimage.img win/ ''} rm -rf win -- 2.42.0 From 0becb115f6fdce9f809fbe02448a89993331c816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Partheym=C3=BCller?= Date: Wed, 10 Mar 2021 11:10:09 +0100 Subject: [PATCH 6/7] win: Use maximum size to split install.wim --- wfvm/win.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wfvm/win.nix b/wfvm/win.nix index 45ffe99..9ee442b 100644 --- a/wfvm/win.nix +++ b/wfvm/win.nix @@ -120,7 +120,7 @@ let rm win/sources/install.wim # Split image so it fits in FAT32 partition - wimsplit win/sources/install_selected.wim win/sources/install.swm 3072 + wimsplit win/sources/install_selected.wim win/sources/install.swm 4096 rm win/sources/install_selected.wim cp ${autounattend.autounattendXML} win/autounattend.xml -- 2.42.0 From f1b52c0da7574929ee0be355edace54387daa52f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Partheym=C3=BCller?= Date: Wed, 10 Mar 2021 13:35:49 +0100 Subject: [PATCH 7/7] autounattend: Revert back to driveLetter D --- wfvm/autounattend.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wfvm/autounattend.nix b/wfvm/autounattend.nix index f79df37..6033b21 100644 --- a/wfvm/autounattend.nix +++ b/wfvm/autounattend.nix @@ -13,8 +13,8 @@ , timeZone ? "UTC" , services ? {} , impureShellCommands ? [] +, driveLetter ? "D:" , efi ? true -, driveLetter ? if efi then "E:" else "D:" , ... }: -- 2.42.0