RAMsteam
-
From BIOS enable network booting, usually some weird on-board LAN setting which has to be enabled, then the BIOS settings applied –> reboot, then back to BIOS, then boot options, then PXE over IPV4 should appear.
-
Make a USB stick which has netboot.xyz on it, or configure your DHCP server to pass out boot options to TFTP server which has
.ipxe
file. -
From the iPXE menu, select the shell option. Type in
chain -a http://boot.ponkila.com/menu.ipxe
. Then, select optionu-root
. Then, fromu-root
prompt writedhclient -ipv4
. Wait a long time or Ctrl+D when you get an IP from DHCP server (this assumes you have a DHCP server). -
Type
wget http://boot.ponkila.com/initrd
and thenwget http://boot.ponkila.com/phasedKernel
. Then,wget http://boot.ponkila.com/netboot.ipxe
. Then,cat netboot.ipxe
. This will show the path of theinit
process, which is prefixed asinit=/nix/store/...
. You will have to manually write this long hash into the next command:kexec --load phasedKernel --initrd=initrd -c "boot.shell_on_fail nvidia-drm.modeset=1 init=/nix/store/..."
. Then,kexec -e
. -
You will boot to crashed NixOS, press
f
for PID1 emergency shell. Writeip a
to see your network interfaces. One of them shows the Ethernet interface, usually something likeenp5s0
or similar. Next, configure your IP manually. Suppose your DHCP server is192.168.1.1
(you have to figure this out on your own). Writeip a add 192.168.1.100/24 dev enp5s0
(e.g., any available IP in your DHCP range), thenip link set enp5s0 up
. Then,ip r add default via 192.168.1.1 dev enp5s0
. Then,vi /etc/resolv.conf
and writenameserver 1.1.1.1
. Check thatping 1.1.1.1
andping google.com
works. -
Now,
wget http://boot.ponkila.com/squashfs.img
. Then, remove the previous squashfs image in your/
folder:rm nix-store.squashfs
. Then,mv squasfs.img nix-store.squashfs
. -
Write
./init
. This will give you prompt you toswitch_root
. Type:switch_root /mnt-root /nix/store/.../init
Tip: you can autocomplete theinit
now by the following: start writing/mnt-root/nix/store/
and then add the first few characters from theinit
hash. Then, you have to go back in the buffer, then remove the/mnt-root
prefix. Once your buffer looks likeswitch_root /mnt-root /nix/store/.../init
, you can press Enter. The system will boot to stage 2 and then to final environment. Commands likesway
andsteam
should now be present, or with a hint of luck, even work properly.
It’s also possible to replace the step 7.
by manually
formatting the filesystem. This probably does not work on NixOS, so this
is for documentation only:
-
The ramdisk filesystem is declared in this file. With this file as reference, proceed to format the filesystem manually:
-
First, the
/
path:mkdir /mnt-root
. Then,mount -t tmpfs none /mnt-root -o mode=0755
. -
Then,
mkdir -p /mnt-root/nix/.ro-store
. Then,losetup squashfs.img
. This will print the loopdevice to which it was attached, such as/dev/loop0
. Then, use this here:mount /dev/loop0 /mnt-root/nix/.ro-store
. -
Then,
mkdir -p /mnt-root/nix/.rw-store
. Then,mount -t tmpfs none /mnt-root/nix/.rw-store -o mode=0755
. -
Then,
mkdir -p /mnt-root/nix/store
. Then,mkdir /mnt-root/nix/.rw-store/{store,work}
Then,mount -t overlay -o lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/store,workdir=/mnt-root/nix/.rw-store/work overlay /mnt-root/nix/store
. -
Then,
switch_root /mnt-root /nix/store.../init
. The system will try to switch root, but probably fail, unless the host OS happened to havesystemd
. Nevertheless, this shows how the filesystem is prepared. -
Tell your friends you know how Linux initialization process works?
Takeaways
This explains more or less how Linux boots. First, you have your
kernel, which for us was named phasedKernel
. In this file,
you will have your drivers and whatnot features enabled. For example, if
you don’t have Ethernet drivers embedded in your kernel (either as a
module or as a yes option), you would not see your interfaces when
running ip a
. Similarly, you wouldn’t have loopdevices
unless you have that feature as well. Same goes for any filesystem
(tmpfs, squashfs, overlayfs) that we used. Gentoo is quite big on making
these bespoke kernels – the smaller the kernel, the faster the boot
time, but more chances that something is really slow, or just
outright broken.
On the other hand, the initrd
is the initial ramdisk (or
initial RAM file system – initramfs, as the name suggests) which is what
you get when you crash into these bare-bones environments. These are
where the userspace tools like ip
and mount
live. Unless these would be located in your /bin
folder,
you could not do much. These usually come from some project, such as
u-root
, or BusyBox
. These binaries usually
have less features than the ones you find from “full desktop”
environments, mostly to save space and for compatibility, but more-so to
make your question whether the bugs you might run into in
inird
are caused by those space-saving trade-offs rather
than user errors. Jokes aside, these tools exist solely to make it
possible to eventually reach the same conclusion, which is to pivot, or
switch_root
. Reaching this step might require decryption of
file-systems, but for us, it’s mostly about network configuration. Note:
the switch_root
resembles what chroot
does,
and by that extend, containers. Again, Gentoo wiki has more on this.