January 27, 2015

USB bootable NixOS

Currently NixOS doesn’t boot straight from a USB stick. There is a PR nixos: iso-image: use syslinux bootloader for USB booting support opened for that, so it should be supported in future.

Below I would like to describe how one can turn current NixOS ISO (boots only from the CD-ROM) into a USB-bootable image which you can write onto your USB device and boot from.

Extract NixOS ISO to a directory

laptop ~ # mount -o loop nixos-graphical-14.12.335.676e8d7-x86_64-linux.iso /mnt
laptop ~ # mkdir iso
laptop ~ # rsync -a /mnt/ iso/
laptop ~ # 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.

laptop ~ # syslinux -v
syslinux 4.05  Copyright 1994-2011 H. Peter Anvin et al

laptop ~ # mkdir iso/syslinux
laptop ~ # cp /usr/lib/syslinux/isolinux.bin iso/syslinux/syslinux.bin
laptop ~ # cp /usr/lib/syslinux/vesamenu.c32 iso/syslinux/

Create new syslinux config based on the original one

laptop ~ # cat iso/loader/entries/nixos-livecd.conf 
title NixOS LiveCD
linux /boot/bzImage
initrd /boot/initrd
options init=/nix/store/hafgpc3gyqsjhj2827yzqj1yh3nfv8v2-nixos-14.12.335.676e8d7/init root=LABEL=NIXOS_ISO boot.shell_on_fail loglevel=4

laptop ~ # nano -w iso/syslinux/syslinux.cfg

laptop ~ # 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/hafgpc3gyqsjhj2827yzqj1yh3nfv8v2-nixos-14.12.335.676e8d7/init root=LABEL=NIXOS_ISO boot.shell_on_fail loglevel=4

Generate new ISO with embedded syslinux

laptop ~ # mkisofs -o nixosusb.iso -V NIXOS_ISO -R -b syslinux/syslinux.bin -c .boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table iso/

Test your ISO image using qemu

laptop ~ # qemu-system-x86_64 -enable-kvm -cdrom nixosusb.iso

Make it USB-bootable now

laptop ~ # isohybrid nixosusb.iso

And test if it boots

laptop ~ # qemu-system-x86_64 -enable-kvm -hda ./nixosusb.iso

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!

laptop ~ # pv < nixosusb.iso > /dev/sdb
laptop ~ # echo 3 > /proc/sys/vm/drop_caches ; sync

That’s all! Now you can run NixOS from your USB stick on almost any PC/laptop and install it :-)

Troubleshooting

In case if your NixOS doesn’t boot, you can run following command to troubleshoot the boot process using qemu:

vaio ~ # qemu-system-x86_64 -enable-kvm -cdrom nixosusb.iso -kernel iso/boot/bzImage -initrd iso/boot/initrd -m 512 -nographic -serial stdio -append "init=/nix/store/hafgpc3gyqsjhj2827yzqj1yh3nfv8v2-nixos-14.12.335.676e8d7/init root=LABEL=NIXOS_ISO boot.shell_on_fail loglevel=4 boot.trace console=ttyAMA0 console=ttyS0"

It implies boot.trace kernel argument and will also dump all the output to stdin so that you can read the boot process. For more kernel argument options please refer to Chapter 20. Troubleshooting – 20.1. Boot Problems

Notice that I also omitted -enable-kvm switch in order to delay the boot process, it might help in some cases to see more.

In some cases, you may want to troubleshoot it live and see more details at particular moments of time. In this case I can suggest to omit the -enable-kvm switch (to slow down the qemu) and use Ctrl+Z, fg in order to pause and continue. Or use Slow down the CPU emulation by (approximately) percent patch.