Booting built kernels with PXE
Linux kernel development can be made a lot nicer by automating some steps in the process. Sadly, there is no shared software package which performs this kind of automation. Most everyone who takes kernel development seriously ends up writing their own tools tailored to their environment. I thought I’d spend a few blog posts sharing the tools I’ve thrown together over the years.
I first tried writing this in a tone which didn’t assume that the reader already knew about kernel development, but it just didn’t work. So, my apologies to those who have no idea what on earth I’m talking about here.
I thought I’d start by describing scripts which help remove the irritating step of installing a new kernel on a test machine’s local drive. Doing so speeds up the compile-boot-test cycle. It goes something like this.
First, I install extra e1000 cards in all the machines so that I can use their PXE boot ROM to boot kernels and initrds over the network. This may not be a great fix for everyone, it just happens to work for me because I was given a box of discarded e1000 cards.
Distros tailor initrds to the hardware of a specific machine (foolishly, I believe, but here we are). To get each machine booting its own initrds I configure dhcpd to point each host at a specific pxe.cfg which in turn references initrds for that host. Each pxe.cfg is built from a per-architecture stub by a script.
The initrds are generated from a copy of the initrd which the distro built for a given host. A script simply replaces each kernel module in the distro’s initrd with the kernel module from the newly built kernel. It’s only a rough approximation of correct behaviour but it has worked so far.
The next problem is that the distro assumes that it will find all the modules for this kernel in the root file system. To accomplish this the script includes all the modules in the initrd. It mounts the root file system read-write and uses a statically linked rsync to copy all the modules from the recent build of the kernel into /lib/modules on the host. It then remounts the root fs read-only before continuing on with the boot.
That’s it, really. Part of this is based on observation that it is, in fact, the 21st century. I’m not booting from 10mbit ether or floppies and don’t care one bit if the initrds are “huge”.
$ ls -hs *2.6.21.1-* 30M initrd-2.6.21.1-syslets 1.8M vmlinuz-2.6.21.1-syslets
Here it is in action:
[zab@kaori 2.6-syslets]$ zk-install-pxe-initrd [zk] preparing initrd for hammer [zk] Warning: hammer needs uhci-hcd.ko [zk] Warning: hammer needs ehci-hcd.ko [zk] Warning: hammer needs ohci-hcd.ko [zk] building initrd for hammer 148402 blocks [zab@kaori 2.6-syslets]$ zk-build-pxe -r [zk] hammer: [zk] 2.6.21.1-syslets [zk] making '2.6.21.1-syslets' the default pxeboot label
[zab@tetsuo ~]# powerman -1 hammer Command completed successfully [zab@tetsuo ~]$ console hammer [Enter `^Ec?' for help] PXELINUX 3.10 2005-08-24 Copyright (C) 1994-2005 H. Peter Anvin boot: Loading hosts/hammer/vmlinuz-2.6.21.1-syslets................................ Loading hosts/hammer/initrd-2.6.21.1-syslets.......................[many, many, dots] Ready. [ 0.000000] Linux version 2.6.21.1-syslets [...] [ ... ] Fedora Core release 6 (Zod) Kernel 2.6.21.1-syslets on an x86_64 hammer login:
The zk prefix I chose for these little scripts ostensibly stands for “zabbo kernel”, but it’s really an inside joke that refers to the ZK_ prefix that ZeroKnowledge used when reimplementing the entire world in their software. Starting with, no seriously, ZK_TRUE and ZK_FALSE.
jenni wrote:
I have a blog. Let’s keep in touch:)
Posted on 18-Jul-07 at 8:57 am | Permalink