An atypical NixOS install

Posted on November 13, 2016

I am using an old hand-me-down IBM ThinkPad X30 as a low powered server. It has served me well for many years running Debian, but recently I wanted to install NixOS since I’ve already switched over my other computers. This is easier said than done since the X30

  1. does not have an optical drive,
  2. absolutely refuses to boot from USB, and
  3. has only 512 MiB memory (the maximum is 1 GiB but I don’t want to buy more).

I attempted to use the netboot method of installing NixOS but did not succeed very well. The issue appears to be that the initrd created by that method is too large for this low-memory machine. A similar fate happened when I tried to do a network boot directly of the installation ISO.

The method I came up with in the end did succeed quite well. It is not entirely intuitive, but in essence the idea is very simple: Write the install ISO image to a USB drive, then use iPXE to do a network boot of the same ISO file that is on the USB drive. This means that when the NixOS stage 1 boot process attempts to mount the root partition it will succeed since the USB drive you so sneakily created has the expected root device label. The boot will then continue from the USB and you can continue as per the installation instructions.

Preparations

For this little scheme to work you will need

  1. a NixOS installation ISO image,
  2. an empty USB stick that is large enough to hold the ISO image,
  3. the undionly.kpxe file from iPXE,
  4. a DHCP server supporting TFTP and PXE,
  5. a web server.

First, we will download the ISO and put in on a USB stick. This can be done using the dd tool using, for example, the command

# dd bs=4M if=nixos-minimal-16.09-i686-linux.iso of=/dev/sdX

where X is replaced to indicate your USB drive. Be very careful not to overwrite some other disk! The USB drive should after this step have a partition labeled “NIXOS_ISO” and you can, for example, see that /dev/disk/by-label/NIXOS_ISO exists.

Second, create a directory that can be served over TFTP, I will use /srv/tftp here. Place the undionly.kpxe file in this directory:

# mkdir /srv/tftp
# wget --output-file=/srv/tftp/undionly.kpxe \
> http://boot.ipxe.org/undionly.kpxe

It is then necessary to tell the DHCP server to use this directory for TFTP and also set up the special chaining that iPXE needs. I already use dnsmasq as the DHCP server for my small home network and luckily it supports both TFTP and PXE. The example here is therefore for dnsmasq. I followed the instructions of a nice blog post and I ended up adding something like the following to my dnsmasq configuration:

enable-tftp
tftp-root=/srv/tftp
dhcp-userclass=set:ipxe,iPXE
dhcp-boot=tag:!ipxe,undionly.kpxe,10.1.2.3
dhcp-boot=tag:ipxe,http://10.1.2.3/boot.ipxe

Third, create a directory that can be served over HTTP. I will use /srv/www here. It should contain the installation ISO file and also an ipxe file which instructs iPXE to load the ISO file. So I have a directory as follows

# ls /srv/www
boot.ipxe  nixos-minimal-16.09-i686-linux.iso

where boot.ipxe contains simply

$ cat boot.ipxe
#!ipxe

sanboot http://10.1.2.3/nixos-minimal-16.09-i686-linux.iso

and the ISO file is exactly the same file as the one we put on the USB stick earlier.

Of course you will have to change the URL above to one that suits your setup. If you are only wanting to do a single install then a lightweight way to host these files is using the simple web server darkhttpd, but of course any web server works.

Booting and starting NixOS install

With all this setup it is finally possible to boot up the computer. Make sure the USB stick with the ISO is inserted in the computer and power up! To enable network boot on the X30 you must hold down the F12 key to get a boot device menu. In that menu chose the entry starting with “IBA”; in my case it is “IBA 4.1.07 Slot 0140”.

That should be enough, now the computer should start downloading the ISO and initiate the boot process.

If you get timeout error during boot about /dev/root not being available then it may be because the USB drive was not detected. Make sure the USB drive really has a partition labeled NIXOS_ISO.

Closing

So that’s it. I’m now happily running NixOS on my ThinkPad X30! So if you are having a computer with little RAM and no way to boot from physical media then this may be a way to still get NixOS on there.