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
andrey@lanl.gov