(Disclaimer: I will describe something that is unsupported. I have tried this, but it doesn’t mean it will work for you or keep working. Know what you are doing before you actually do.)
Only the steps:
Make sure you’re on UEFI. Get a drive with a FAT32 partition (GPT/MBR partition . And either:
Method one
Unpack everything to the root of your drive, and do either:
- Boot from the drive until the boot process fails, enter interactive shell by pressing
i
, mount your partition at/mnt-root/iso
or wherever it says the device couldn’t be mounted at, and exit the shell to continue the boot, or - In
/EFI/boot/grub.cfg
replace every instance ofroot=LABEL=...
withroot=/dev/disk/...
, where/dev/disk/...
identifies your FAT32 partition.
Method 2 using findiso
- Unpack only the
/boot
and/EFI
directories from the.iso
into the root of your drive - Copy the
.iso
file itself into your drive - Prepend the following line to
/EFI/boot/grub.cfg
, replacing the file name with your actual.iso
file name
set iso_path=/latest-nixos-plasma5-x86_64-linux.iso
For some reason copytoram
doesn’t seem to work for this method.
Again, these are based on my own understanding and experimentation and are not in any way official or supported.
The following is based on my experience with NixOS 20.03.
The problem
As we all know, using dd
is the officially supported way to create a NixOS drive from an image, and it is in fact the case for many (most?) other distros as well. But one drawback of this method is also obvious: you lose your partitions in your drive, and if you want to use it as a normal drive you have to repartition and reformat it.
One thing I’ve heard is that for UEFI systems, most of these .iso
files (even Windows ones if the largest file fits in 4GB) can be directly unpacked to a FAT32 drive. Then UEFI recognizes /EFI/boot/bootx64.efi
and runs it, which is a bootloader that loads the rest of the live system.
However this doesn’t seem to work with NixOS images. The part where things get stuck is that the images waits for /dev/root
to appear, but it doesn’t, so it fails to boot.
What to do
If at this point you want to continue, you can go in a shell by pressing i
. You’ll see that it’s trying to mount /dev/root
which symlinks to a non-existing partition with label like nixos-plasma
… which is of course would be the ISO had you used dd
, but you only copied the files to your partition. The boot however will work with your partition. Now if you just mount your drive to /mnt-root/iso
and exit the shell, boot will happily continue and the rest of the boot drive works just as well as a dd
-made one, as far as I can see.
On the other hand you can also fix the cause. /dev/root
is specified according to the root=...
kernel comman,d line parameter. So just find some persistent way to refer to your partition like /dev/disk/by-partuuid/<foo>
and you can simply go into /EFI/boot/grub.cfg
and replace every occurence of root=...
with root=/dev/disk/by-partuuid/<foo>
, and you have a fully working NixOS boot drive.
The truth, and more…?
All this happens in what’s called ‘stage 1’ of the NixOS boot process. stage-1-init.sh
contains literally everything about the early boot process (userland part, of course).
Here we also find other mysterious stuff. What’s findiso
? Can we also use this to create bootable images by copying out only bootloader+kernel+initrd, and adding a findiso
parameter? Why is it undocumented? I have not yet investigated.
Also, I haven’t used Unetbootin, so I don’t know anything about that.
Clicky stuff
- As mentioned,
stage-1-init.sh
is a gold mine of information on how NixOS boots up. Check it out on GitHub - This topic was orginally brought up on IRC a while ago:
-
oxalica (GitHub) orginally inspired me to investigate the ’
/dev/root
issue’.