This is a continuation of Reviving Xbox-Linux, 15 years later. Refer to that article for an introduction.
As a first step I'm going to try to compile and hopefully boot the latest available Xbox-Linux kernel (2.4.32). The Xbox-Linux page about porting existing Linux distributions to the Xbox suggests starting by making the kernel mount the root filesystem over NFS, as this will make it easier to make changes to it. While I'm not sure these instructions were ever tested, it does sound like a good idea.
The guide also suggests using Etherboot in the Cromwell BIOS to load the kernel over the network. Somebody on the xbox-linux-user mailing list posted instructions for building an Etherboot compatible image from a kernel and an initrd. Gmane has shut down operations so instead of linking I'm re-hosting that e-mail in its entirety here. I tried these instructions initially but never got it to work. Some web searching revealed that csudcy at the LinuxMCE forums tried the same thing in 2007. I basically tried the same steps and got the same results that he did so I won't bother documenting it further. Suffice to say that Etherboot is broken in the latest and last Cromwell (2.41-dev). Maybe it never worked. For now I'll use the built-in FTP server in the UnleashX dashboard that my Xbox runs on startup to transfer my homemade kernels to the hard drive.
Building ancient Linux kernels
There is a decent README in Xbox-Linux's CVS repository on Sourceforge that walks one through the build process of an Xbox compatible Linux kernel.
The first problem is that modern desktops run 64-bit CPU's and operating systems, which didn't exist in 2001 (at least not the amd64 architecture). An Ask Ubuntu user suggests using sbuild to create a 32-bit chroot and build the kernel in that. I created an Ubuntu 16.04 32-bit chroot and attempted a kernel build. It failed with error: array type has incomplete element type 'struct foo_bar'
on a file that it didn't look like the Xbox-Linux patch touched. I figure this is because the current version of gcc (5.3.1) enforces constraints in the C programming language that weren't around when the kernel code was written. The easiest solution is likely to get an older compiler.
In 2001-2004 gcc-3.x was the latest and greatest version. So let's try a Linux distribution that bundles gcc-3.3 or maybe 3.4. This would have to be Ubuntu 5.04 or Debian 3.1 or earlier.
mk-sbuild
can only install Ubuntu releases that are currently officially supported (>=12.04). It can install ancient Debian releases, but I found that debootstrap
tries to use options that the archaic APT doesn't yet understand (--no-install-recommends
).
I was hoping to not have to resort to a virtual machine for this adventure, but right now it seems to be the easiest option. http://cdimage.debian.org/mirror/cdimage/archive/ still serves historical Debian installation ISO images and http://archive.debian.org/debian/dists/ carries binary packages for posterity. Hurray for Debian! So I got the netinstall image for Debian 3.1 i386 and fired it up in VirtualBox.
Installing a prehistoric Debian
First it wouldn't find the HDD because VirtualBox defaults to creating a SATA controller for the hard drives. SATA did actually exist when Debian Sarge was new, but Linux support for it came first with kernel 2.6.19 and Sarge bundles 2.4.27. ref
I also tried enabling multiple CPU cores, and while Debian did boot, only one CPU was detected. Guess when Symmetric Multiprocessing support was added to Linux? Kernel 2.6. Doesn't matter, my 2012 CPU is blazing fast with 2005 standards at single core applications as well.
Eventually the virtual machine booted properly and I was able to install Debian. Since most Debian mirrors drop the packages for unsupported releases I had some trouble configuring APT. I resorted to setting it up with only the installation CD as a package repository so that the installer would continue, and manually added archive.debian.org to /etc/apt/sources.list after the installation.
This just in: Linux-2.4.32
Finally I was able to follow the build instructions in README.xbox. I downloaded linux-2.4.32 from kernel.org and the corresponding patch from the Xbox-Linux project page on Sourceforge. The README mentions that after the bundled kernel.config has been copied to .config, one must run make oldconfig
to "cause some actions to be made by the makefile". I later found that this has to be done every time the kernel configuration has been changed though make menuconfig
, otherwise there would be linker errors during make bzImage
.
Since this is a throwaway build machine, I opted to make modules_install
as root after the compilation to collect all modules into /lib/modules/2.4.32-xbox that I could then tar up and transfer to the Xbox hard drive.
Booting the kernel
Well, it didn't work. To be precise, the kernel did boot, but the init script in the initrd wouldn't find the hard disk. I still consider this part of the project a success, since I was eventually able to compile a bootable kernel image. In the next segment I'll investigate why it wouldn't find the hard drive.
Misc resources
While researching Xbox-Linux and related projects I found some articles that were interesting if not immediately relevant to my projects.
- Porting_an_Operating_System_to_the_Xbox_HOWTO documents peculiarities of the Xbox hardware that an operating system must take into consideration.
- An enthusiastic BSD user ported parts of OpenBSD to the Xbox
- Xbox-Linux wiki Contents has a lot of useful links.