For my birthday this year, my wonderful wife gave me a Silicon Power 2 TB M.2 SSD, which I requested, love, and recommend. It's both a very reasonable price and extremely fast, so it seemed like the perfect little upgrade for my computer until GPU prices come back down. I had previously upgraded my original hard drive to a larger hard drive and then upgraded that to a smaller SSD, so I was familiar with the experience and mostly knew what I was doing.
To start the migration, I just cloned my drive with Clonezilla, like I had before. The ISO I had was (I think) too old to work with my M.2 drive. (It just said
Unable to find target partition "nvme0n1p1".) So I booted into a live Linux image, installed Clonezilla, and copied it from there. Everything worked fine. I booted Windows and all my drives were there. It was complaining that the cloned drives had the same UUIDs as the old ones, but that didn't sound hard to fix.
However, my partitions were still tiny and only filling 13% of my new drive. I rebooted back to Ubuntu to move it away and make both drives larger. After a small skerfuffle of
GParted Bug: A partition cannot end (3651028992) after the end of the device (%2), which was just caused by rounding to the nearest MiB rounding the partition off the end of the drive (so I made 1 MiB empty between), I had my Linux partition resized. (It failed to resize NTFS for who knows why.)
However, I wasn't happy with just one Linux distribution. If I had been, I probably could have just resized C: in Windows and been at peace. Yet I had heard neat things about Nix and wanted to try out NixOS. It had sounded like a more practical alternative to Gentoo, so I downloaded and tried to install it. However, NixOs is unable to install an EFI on a drive with an MBR. (A Master Boot Record is a small partition at the start of a drive, describing the partitions on the drive and how to boot. An Extensible Firmware Interface is the new way to describe how to boot, typically used with the new GPT partition table.)
Since I had always been cloning my C: partition from drive to drive over the years, I never replaced the old MBR with a GPT. I figured now's as good a time as ever, so I used gdisk to convert it.
What a terrible mistake.
I installed NixOS, however it installed systemd-boot. I only really ever have used GRUB, and that's the only bootloader I have tools to edit, so I ran boot-repair and installed GRUB. This turned out to not actually remove systemd-boot and just made nothing boot, but running
bootctl remove removed systemd-boot and everything was seemingly good again.
But…if you convert a drive containing Windows to UEFI without doing it with Windows' mbr2gpt, it seems there's no way to convert Windows anymore. Windows just said "Your PC/Device needs to be repaired. A required device isn't connected or can't be accessed. Error code: 0xc000000e" So, despite having spent hours converting it to GPT and getting Linux working thereon, for Windows' sake, I had to convert it back to MBR.
Thankfully, gdisk supports this too. It goes both ways. However, it does not handle it well. I had the following setup of partitions:
- Windows System Reserved partition
- Windows main "boot" partition
- EFI partition
- NixOS partition
- Ubuntu partition
- Linux swap partition
Since MBR can only handle four logical partitions, I had had my Linux partitions in an extended partition before converting to GPT. I had heard gdisk would handle creating extended partitions, but, uh…it did not. Instead of, say, putting the last three partitions into an extended partition, it instead just deleted them without warning.
This was more than a little scary to me. I always had the backup of copying it from my prior SSD again, but I decided on a riskier approach: remaking the partitions manually. Since gdisk just printed out all the info about the partitions, I could type that into the similarly-named fdisk and theoretically it should work, since all the data was there, just not the partition table.
Thankfully I left a little space for an extended partition's overhead, and this plan actually worked—probably my best performance in this whole debacle.
This didn't magically fix Windows's boot partition, so I had to still repair it from a Windows live image. I quickly threw a Windows 10 ISO onto my USB with Ventoy, which I love, but when I booted it, it said
Status: 0xc000014c Info: The Boot Configuration Data for your PC is missing or contains errors. This took me quite a while to troubleshoot. There didn't seem to be any reason for it. I ran sha256sum on the ISO, and it didn't match. I copied it over again, and the same thing happened. It turned out that I was restarting too soon. As soon as Nautilus said it was copied, I restarted the computer. Yet just because it said it was copied, didn't mean it was. It was copied to the cached version of the drive, but it wasn't actually synced. I waited a little bit longer after copying and ensured the hash maybe, and I was good to go. Alternatively, I could have run
sync before restarting.
With a correct copy of Windows on the drive, I was able to repair the Windows BIOS bootloader without too much issue by copying a new copy from the flash drive using
bcdboot C:\windows /s S:, where S: is the letter I assigned the System Reserved partition using diskpart.
This worked, and I was able to boot into Windows again. However, my drive was still using MBR, so I was largely just back to square one. I figured it was better to plunge back in and try to convert it to GPT now while I kind of knew what I was doing rather than kick the can down the road another few years until my partition outgrew MBR's 2 TB limit. I tried to run mbr2gpt again, but apparently it can't work if a drive has extended partitions. I didn't need any EFI partition for now, so that's one down; by this point, I was pretty fed up with NixOS for a few reasons, so I was fine just deleting that; and then the swap partition was easy to remake and didn't need to be preserved. Yet even after trimming the number of partitions down and making everything a primary partition, mbr2gpt still didn't work. I'm not sure why copying the bootloader over didn't fix it 100%, but Windows still wasn't happy with the BCD.
I rebooted yet again to the Windows Recovery Environment terminal and began running the commands Google recommended. Nothing worked. No matter what commands I ran, nothing seemed to help. In fact, nothing seemed to do anything.
The explanation for this is that most disk utilities on Windows only work with one drive. Since I had multiple SSDs, it was only ever targeting my old drive with most of the commands. mbr2gpt lets you specify a drive, bcdboot and bcdedit do too, but bootrec doesn't. Its only flags are for which operation you want it to do. bcdedit is powerful, but no matter what I did with it, mbr2gpt wasn't happy. So the only way I had to repair my BCD was to remove every other drive so that the drive I wanted would be disk 0 and I could use bootrec. I didn't want to open my case again and physically unplug everything and then have to plug it back in, but I rebooted into my motherboard's UEFI interface and disabled all my other drives there (except the flash drive). Then, after booting back into the Windows Recovery Environment, I ran
bootrec /rebuildbcd and then
mbr2gpt /convert /disk:0.
This finally worked. I saw those three beautiful words: "Conversion completed successfully" It might be worth noting but I also deleted my Linux partition off the drive first and cloned it back over after. I don't think this was required, but I can't be sure how Windows would handle it.
I then rebooted excitedly, aaand it gave me a new error:
Your PC couldn't start properly
After multiple tries, the operating system on your PC failed to start, so it needs to be repaired.
Error code: 0xc0000001
This makes it sound like there's something wrong with the BCD even though it was successfully converted to an EFI. Thankfully that is not the case. What's actually happening here is that the motherboard is still in BIOS mode, so it's trying to load Windows's MBR, which no longer exists fully. All you have to do to fix this is going to your motherboard settings and enable UEFI boot instead. Windows then finally boots correctly off a GPT drive.
Again, in theory, there's nothing stopping you from booting with a BIOS on a GPT drive (since it has a protective MBR) or an EFI on an MBR drive, but in practice nothing seems to support this, especially not Windows. MBR and BIOS support have been maintained as legacy options, and GPT and EFI are the intended systems. No one seems to have taken the effort to enable mixing and matching these together. If you really knew what you were doing though, you could probably hack something together, but I only know enough to be dangerous, and frankly, I don't see a reason to do that.
Anyway, booting Windows seemed to be working now, but emphasis on "seemed". And even though I was disappointed in NixOS, I still wanted to continue dual booting with Ubuntu. So I booted into boot-repair yet again and ran it. Was a mistake for again while everything seemed to work fine, there was an underlying problem which I soon discovered.
See, cloning a drive is very thorough. Not only did it clone the partitions, the data therein, and the partition table, but it even clones the drive ID. This was what Windows was complaining about initially, even though it handled it pretty seamlessly. Bootloaders, on the other hand, did not handle it well. GRUB, at least by default, selects drives by their UUIDs. When two drives had the same UUID, it seemed to just boot one at random, regardless of which drive's operating system I picked. Usually it chose my old drive. This was a simple fix: I just had to generate a new UUID, which was easily done in GParted, but it's quite insidious if you don't notice.
After regenerating GRUB yet again, everything was actually, finally done this time. Almost left to do is reformat the old drives when I'm convinced I won't need them anymore. I strongly hope I will never have to do this again, but hopefully this written experience will help any other late migrators in the same unfortunate circumstance.