Multiboot USB
Windows
History
I had squeezed a CentOS Stream install onto the end of a Windows 10 laptop. All was fine until the CentOS Stream decided it would no longer upgrade because something something modular packages. Fedora Server 32 wouldn't install (me? it?) so I installed CentOS 7 to check. CentOS 7 was fine but ... Windows 10 was now missing. Not just the menuentry in grub.cfg but the EFI boot contents were missing. Something (no finger pointing but only CentOS was involved) had deleted the /boot/efi/EFI/Microsoft hierarchy.
*aiee!*
I managed to resurrect the grub.cfg contents -- to discover the missing hierarchy -- and then copied that hierarchy off another box. *bzzzt!* No deal. In the hierarchy is a BCD database (and replicas) and the physical disks didn't line up.
So, put a copy of Windows 10 on a USB stick and boot? There, my friends, we get stuck.
Microsoft have changed their tune with Windows 10 and even actively encourage you to download ISOs for their Creators stuff. I know one person who swears by Rufus for creating Windows USB sticks and a lot of web sites are now saying to install WoeUSB. My idea of a CLI solution isn't to download a package that does it for you. What's the deal?
Size Matters
There is a complication in the usual "newer is bigger" sense. Modern versions of Windows 10 (this is 2020) are not just more than 4GB in size they contain an individual .wim file (no idea) that is over 4GB. That won't work for FAT32.
There are some wimtools which will compress a .wim file for you but the only real solution is to use NTFS -- much like we've used XFS for the multiboot solution.
The ntfs-3g package is available to diddle with NTFS but you might have to build it from source depending on the whims of the CentOS/Fedora package managers.
I don't know how that would affect the following. I used a copy of Windows 10 1607 I had lying around which is just on the 4GB cusp.
Windows UEFI
First up, you can't simply dd the ISO onto a USB stick because that would be too easy.
No, you need to create a gpt partitioned USB stick and copy the contents of the ISO (not copy the ISO). You also need a magic partition flag.
parted
Given your favourite USB stick, check which device it is with lsblk:
# lsblk -f -o +SIZE,MODEL NAME FSTYPE LABEL UUID MOUNTPOINT SIZE MODEL ... sdf 28.7G Ultra Fit
Trash it:
# dd if=/dev/zero of=/dev/sdf bs=4M count=100
Build it back up:
# parted /dev/sdf (parted) mklabel gpt (parted) unit s (parted) mkpart fat32 2048s 60061695s
You may get prompted as it tries to align the sectors, that's OK.
Final magic trick:
(parted) set 1 msftdata
Normally you might be tempted to enable the boot flag but not here.
CentOS 7, I notice, doesn't support the msftdata flag . I've seen it expressed as a different partition type elsewhere which you might be able to set with fdisk.
Copy
We need to mount both the USB and the ISO file:
# mkdir /tmp/{usb,iso} # mkfs.vfat /dev/sdf1 # mount /dev/sdf1 /tmp/usb # mount -t auto -o loop /path/to/Win10.iso /tmp/iso
and now copy the contents. I initially tried a tar but I think we get caught by restrictive directory permissions being applied before the contents are added. Old school says:
# (cd /tmp/iso; find . -depth | cpio -pdum /tmp/usb)
-depth is the trick with find to force it to recurse before "declaring" the directory. cpio takes it in its stride.
If you have a machine with a lot of memory you need to wait for it to be flushed to disk:
# time sync
then tidy up:
# umount /tmp/iso # umount /tmp/usb
and you have a bootable Windows 10 USB stick. Using actual command line tools.
Windows UEFI Repair
Credit to this page for the details:
Your Windows 10 USB stick is probably intent in installing Windows. You need to click Next on the first page then Repair on the second.
From there click Troubleshoot (possibly Advanced Options) and Command Prompt.
Now the fun starts, we need to get Windows to recognise, uh, Windows.
One suggestion is bootrec and its /FixMbr, /ScanOs and /RebuildBcd options. None of which did anything for me.
Next step is to play with diskpart and get it to mount the ESI partition.
We start by listing them:
c:> diskpart DISKPART> list vol
You now need to identify your ESI partition from the volumes the ones presented. It should be a FAT or FAT32 partition and is unlikely to be more than 1GB. If it was a reasonably recent Windows install it is quite likely to be volume 2. Which we need to select:
DISKPART> sel vol 2
We get access to it by giving it a drive letter:
DISKPART> assign letter=G:
(something unique!)
and quit:
DISKPART> exit c:>
Switch over to G: and work you way down to the Boot area:
c:> G: g:> cd EFI/Microsoft/Boot
(or something)
Finally we can recreate the BCD with:
g:> bcdboot c:\Windows /l en-gb /v
dir should show a recently modified BCD file amongst others.
Multiboot Windows
We can't use our usual multi boot trick for Windows as it complains that the (loopback mounted) image isn't right in some way.
That gives me an idea -- untested, of course. If we go down the route of the multi-boot USB stick but add one (or more) partitions for Windows. We can extract them in this way and fiddle with grub.cfg to chainload them in the usual way.
Document Actions