Booting plan9 from flash
Changes to the Plan 9 loader (9load) and the Plan 9 kernel to allow booting of Geode nodes without any present BIOS. Hardware used: http://www.advantech.com/products/Model_Detail.asp?model_id=1@30541 Configuration: The configuration uses LinuxBIOS as the initial bootloder, LinuxBIOS does some hardware initialization and jumps to 9load, masqueraded as a linux kernel at address 0x800000. 9load has to run here because the kernel needs to load at 0x100000. It can't load at < 0x100000 because that is owned by linuxbios. We had to make some changes to 9load to make this go (like linking it at 0x800000 for example :) 9load then does standard Plan 9 configuration, finds and initializes the present RTL8139 cards and attempts to download a kernel from what it has configured as ether0. If the download is succesfull 9load jumps to the kernel at 0x100020; otherwise it prompts (on the serial port) for a normal 'boot from:' selection. The Plan 9 kernel (a CPU kernel) then does the usual dance, finding devices, etc, and boots from IL without user intervention. Hard drives are not present and not required. Monitors are optional (depending on hardware they may or may not work, vga hardware initialization is not something we do in Plan 9). Rio will, generally, not work. Currently no work is being done in having Rio start in a bios-less configuration. When necessary, one can always attach a serial console to a node booted in the above configuration and will get a prompt. Changes in general libraries: libboot: modified to accept an extra possible location for nvram, namely the machine's CMOS, aka #r/nvram (see devrtc.c) details and explanation follow (the devrtc section below) factotum: needs to be recompiled (uses above library) and relinked with the kernel. auth/keyfs: needs to be recompiled if one's to utilize the node as a cpu server. Changes in 9load: ether.c: modified to probe for ethernet cards rather than expect it to be configured from plan9.ini (there is no plan9.ini). all ether devices found are given irq 9 (the geode hardwires the INTP lines to 10, but for some reason 10 does not work) l.s: the real mode code is commented out (rather, ifdef'd), 9load is entered in protected mode. code is added to load the GDT. some attempts to fix the IRQ routing problem but nothing is tested extensively. we ended up chasing a bug for a long time with: MOV AX, SS and ended up fixing it somewhat miraculously. it never appears in normal bios boots... load.c: hardcoded to boot off 'ether0' as soon as it has finished finding and configuring the (missing) pci devices and hard drives. if the bootp off ether0 fails (e.g. a bad kernel is given) load.c prompts for another boot device. the 'i'm too big' check is commented out. console support is hardwired (no plan9.ini to turn it on). Changes in the kernel: configuration files -- all unnecessary hardware drivers are removed. this is not really needed, but it's done to get the kernel size down to 365Kbytes (compressed). it also facilitates a bit faster booting, though a lack thereof is not really an issue either. devrtc: changed Nvoff to 0x10 from 128. this allows us to store the cpu server's login information in CMOS, rather than requiring a nvram partition on a floppy or a hard drive, or entering the password every time the machine reboots. the byre configuration is as follows: (bank 1): 0x0 to 0xD real time clock 00E diagnostic status byte 00F shutdown status byte 010 to 07F where NVram lives note: normally one would not like to change the nvram on a machine with a normal BIOS -- some important configuration information is left there (fixed disk info, disk drives info and so on) and the BIOS generally will complain and have you reconfigure it or reload defaults. it's a tight spot to store the nvram in, but it'll do for now. this new stuff is used by libboot. main.c: the kbdinit() call in main() is moved earlier to help with debugging. memory.c: debugging turned on. Plan9 misconfigures its main memory when there's no bios present, causing the Proc structure initialization to overwrite the kernel. some values are hardcoded here for 128 megs of ram (irregardless of how much ram there is) until someone spends enough time to fix it. pci.c: cyrix irq initialization is changed, together with the way p9 sets the interrupts. this is untested on other hardware and is a bit tailored towards our current hardware. needs more work before a patch is submitted, ethernet irqs hardwired to 9, others untouched (it may be a geode bug). uarti82590.c: hardcoded console on eia0 (no plan9.ini to configure it) Conclusions: It could be done. More conclusions: As thorough as Plan9 is to create bug-free code, we found that it is sometimes too trusting in the hardware it runs on. Unfortunately it would require some time to make it work on some of the more unfriendly hardware that some of us would like to see it... Timing: Time to boot from power on to a fully functional kernel is ~30 seconds. It could be made faster by not printing extensive debugging information, by not probing for hard drives or network cards we don't have and so on. We think 30 secs is pretty decent and quite satisfactory. Future tests will have to deal with booting large numbers of nodes and finding out whether the bootp server in P9 can handle larger loads.
Last Modified: Jun 09 2002