To expedite the development of my contemplated Xbox rsync file server Linux distribution, I would like the ability to mount the root filesystem over the network using NFS. The kernel requirements for is documented in Documentation/filesystems/nfs/nfsroot.txt
in the kernel source tree. nfsroot was slightly less featureful in 2.4 than in the current kernel, so make sure to get the old version if you are coding along. Also, if you are coding along then please do get in touch so I will know that I'm not the only person in the world to program for the classic Xbox in 2016.
Continuing from Booting X-DSL with a custom kernel where we disabled devfsd via kernel config patch, a suitable linuxboot.cfg
for nfsroot looks something like this:
title XDSL unstable 2.4.32 NFS root
kernel KNOPPIX/bzImage.32
append root=/dev/nfs nfsroot=/srv/xbox-linux ip=192.168.1.188:192.168.1.21:::::off init=/etc/init rw video=xbox:640x480 kbd-reset
Note that no initrd should be necessary. 192.168.1.188 is the client (Xbox) IP address and 192.168.1.21 is the NFS server IP address. I could have used more DHCP (the kernel built in this article supports it) but then I would also have to reconfigure my DHCP server, and that seemed like a lot of work for this toy project.
Start by opening fs/nfs/nfsroot.c
and replacing
#undef NFSROOT_DEBUG
with
#define NFSROOT_DEBUG
to get some feedback from the NFS mounting process. Otherwise you will just get the uninformative message of
VFS: Cannot open root device "nfs" or 00:ff
Please append a correct "root=" boot option
Kernel panic: VFS: Unable to mount root fs on 00:ff
which tells you that /dev/nfs, which was specified in the root
kernel command line parameter, was not set up correctly.
KCONFIG time
I will present several patches in this section. To keep track of them I recommend using the program quilt as I wrote about in a separate article.
Referring to Documentation/filesystems/nfs/nfsroot.txt
, the first thing to enable is NFS support and IP autoconfiguration. Apply enable-nfsroot.patch, make bzImage
, transfer the kernel image and boot.
This should fail because there are no network adapters available. The reason for this is that the Ethernet driver is built as a module instead of being included inside the kernel image. For a special purpose Linux distribution like X-DSL or Xebian that will basically never be run on anything other than an actual Xbox, there is no gain in having essential drivers in modules.
Apply enable-builtin-nforce-driver.patch and try again. Now NFS will actually fire up and try to mount the root filesystem. There is confusion between the client and server however, resulting in errors being printed in the kernel console. Examining the situation closer using Wireshark revealed that the ancient Linux 2.4 kernel tries to use NFSv2 instead of version 3 or 4 which are more common today. The NFS server on my desktop computer (Linux 4.4) claims to still support NFSv2, but it doesn't seem to work very well. If the client requests a non-existing file, the server appears to respond with an "unsupported operation" which seems strange to me.
Fortunately I won't have to downgrade my desktop to Linux 2.4, since the kernel does support NFSv3, it's just not the default (yet). To enable support for it, apply enable-nfsv3.patch and rebuild. Also add v3
as an NFS mounting option in linuxboot.cfg
like so:
append root=/dev/nfs nfsroot=/srv/xbox-linux,v3 ip=...
If you are using quilt, your series
file should at this point look like this:
disable-devfs.patch
enable-nfsroot.patch
enable-builtin-nforce-driver.patch
enable-nfsv3.patch
(Partial) Success
Finally, the root filesystem is mounted and the system boots! Almost... It fails during fsck because the device backing the root filesystem (normally /dev/loop0) is not found. Disabling fsck in /etc/fstab fixes this and allows the boot procedure to continue and eventually land in a proper root shell.
However, the system will not shut down cleanly. At this part it becomes clear that DSL is maybe not a very solid foundation to build a specialized operating system on. The major part of X-DSL's shutdown process is implemented by a gigantic pile of shellscript in /etc/init.d/knoppix-halt. As part of this procedure, the network interfaces are disabled before the filesystems are unmounted. It should in theory unmount network filesystems first but, being a gigantic pile of shellscript, it understandably isn't completely reliable. I guess this is what they call a "minimalistic init system".
I could try to reorder lines in this file, but that would create a maintenance burden that I'm not very interested in. I might come back to this later, but first I should investigate Xebian, a Debian port for the classic Xbox. The reason I tried X-DSL before Xebian is that it seemed to have been maintained for longer. Xebian basically had one major release with some minor updates before its developers moved on. Still, being based on Debian I expect it to be fairly versatile and solid.