Previously I wrote how to make USB bootable NixOS.

This time, I’ll cover the UEFI part so that you can boot NixOS with UEFI

Successfully tested on Lenovo ThinkPad T430 and Sony VAIO 13 Touch Ultrabook.

Extract NixOS ISO to a directory

mount -o loop nixos-minimal-14.12.335.676e8d7-x86_64-linux.iso /mnt mkdir iso rsync -a /mnt/ iso/ umount /mnt

Copy syslinux files to extracted NixOS

Depending on the version of syslinux, there are special considerations what directory and the config name should be.

mkdir iso/syslinux cp /nix/store/hash-syslinux-6.03/share/syslinux/isolinux.bin iso/syslinux/syslinux.bin cp /nix/store/hash-syslinux-6.03/share/syslinux/vesamenu.c32 iso/syslinux/

with syslinux v6.03 you also need to copy these files:

cp /nix/store/hash-syslinux-6.03/share/syslinux/ldlinux.c32 iso/syslinux/ cp /nix/store/hash-syslinux-6.03/share/syslinux/libcom32.c32 iso/syslinux/ cp /nix/store/hash-syslinux-6.03/share/syslinux/libutil.c32 iso/syslinux/

Create new syslinux config based on the original one

[ root@nixos:~]# cat iso/loader/entries/nixos-livecd.conf title NixOS LiveCD linux /boot/bzImage initrd /boot/initrd options init = /nix/store/y606cp5rf75kfz8g36dcyaki2is79kcm-nixos-14.12.335.676e8d7/init root = LABEL = NIXOS_ISO boot.shell_on_fail loglevel = 4 [ root@nixos:~]# nano -w iso/syslinux/syslinux.cfg [ root@nixos:~]# cat iso/syslinux/syslinux.cfg UI vesamenu.c32 PROMPT 1 TIMEOUT 50 DEFAULT nixos SAY Now booting the kernel from SYSLINUX... LABEL nixos KERNEL /boot/bzImage APPEND ro initrd = /boot/initrd init = /nix/store/y606cp5rf75kfz8g36dcyaki2is79kcm-nixos-14.12.335.676e8d7/init root = LABEL = NIXOS_ISO boot.shell_on_fail loglevel = 4

Set the volume label to efi.img

If you look at nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix , the efi.img was created without a label. It is crucial to set any label but not equal to NIXOS_ISO as we will generate ISO with this label -V NIXOS_ISO later

[root@nixos:~]# mlabel -s -i iso/boot/efi.img Volume has no label [root@nixos:~]# mlabel -i iso/boot/efi.img ::EFIBOOT [root@nixos:~]# mlabel -s -i iso/boot/efi.img Volume label is EFIBOOT

Without this label, on UEFI boot, stage1 can’t mount the root device which is necessary for stage2 boot process to continue. However it is possible to workaround this by modifying kernel argument manually on boot to root=/dev/sda1 OR root=UUID=2015-02-03-10-11-46-00 OR root=/dev/disk/by-uuid/2015-02-03-10-11-46-00 instead of the default root=LABEL=NIXOS_ISO

Generate new ISO with embedded syslinux and efi.img

genisoimage -o nixos-live-usb-uefi.iso -V NIXOS_ISO -R -b syslinux/syslinux.bin -c .boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot iso/

Make it USB-bootable now

isohybrid --uefi nixos-live-usb-uefi.iso

Test your ISO image using qemu and UEFI

Download OVMF binary. It enables UEFI firmware for QEMU and KVM so that you can test your ISO before writing it on your USB stick.

CDROM Legacy (BIOS)

qemu-system-x86_64 -enable-kvm -cdrom nixos-live-usb-uefi.iso

CDROM UEFI

qemu-system-x86_64 -enable-kvm -bios ./OVMF.fd -cdrom nixos-live-usb-uefi.iso

USB Legacy (BIOS)

qemu-system-x86_64 -enable-kvm -hda nixos-live-usb-uefi.iso qemu-system-x86_64 -enable-kvm -usb -usbdevice disk:nixos-live-usb-uefi.iso

USB UEFI

qemu-system-x86_64 -enable-kvm -bios ./OVMF.fd -hda nixos-live-usb-uefi.iso qemu-system-x86_64 -enable-kvm -bios ./OVMF.fd -usb -usbdevice disk:nixos-live-usb-uefi.iso

As -usb runs very slow, I intentionally specified both -hda and -usb because in most of cases if -hda boots then -usb also boots.

Write your ISO

Now it’s time to write your USB-bootable image onto your USB stick (in my case it was accessible at /dev/sdb )

Be very careful using following commands, do not to overwrite any of your other devices!

[ root@nixos:~]# cat nixos-live-usb-uefi.iso > /dev/sdX [ root@nixos:~]# echo 3 > /proc/sys/vm/drop_caches ; sync [ root@nixos:~]# udisksctl power-off -b /dev/sdb

Now you can try booting with UEFI.

Secure Boot

If you will see similar error as this one, then all you have to do is to disable Secure Boot from your BIOS options, but keep UEFI enabled. If you really want to have Secure Boot then see this for an overview.

Secure Boot Image failed to verify with *ACCESS DENIED*. Press any key to continue.

additional notes

Create EFI partition

If you wish, you can create/modify EFI partition on your own as follows

dd bs = 2048 count = 5120 if = /dev/zero of = "iso/boot/efi.img" mkfs.vfat -n "EFIBOOT" "iso/boot/efi.img" mcopy -svi "iso/boot/efi.img" iso/efi iso/loader :: mmd -i "iso/boot/efi.img" boot mcopy -v -i "iso/boot/efi.img" iso/boot/bzImage ::boot/bzImage mcopy -v -i "iso/boot/efi.img" iso/boot/initrd ::boot/initrd

Checking the lables

[ root@nixos:~]# blkid iso/boot/efi.img iso/boot/efi.img: SEC_TYPE = "msdos" LABEL = "EFIBOOT" UUID = "98D2-735E" TYPE = "vfat" [ root@nixos:~]# blkid nixos-live-usb-uefi.iso nixos-live-usb-uefi.iso: UUID = "2015-02-03-10-11-46-00" LABEL = "NIXOS_ISO" TYPE = "iso9660" PTUUID = "42719253" PTTYPE = "dos"

Xorriso version

Using this method you don’t have to run isohybrid --uefi command