Subject: proposed re-work / unification of boot block installation
To: None <tech-kern@netbsd.org>
From: Luke Mewburn <lukem@wasabisystems.com>
List: tech-kern
Date: 03/12/2002 14:58:03
Here's a proposal for a re-work of the boot block installation under
NetBSD.  I've posted it here for feedback, even though it's just as
relevant in tech-install; saves cross-posting.


--- cut here --- file: netbsd/wip/installboot/spec

		NetBSD Boot Block Re-organisation
		---------------------------------

		Luke Mewburn <lukem@netbsd.org>
		Tue Mar 12 03:49:23 UTC 2002

1. Introduction
---------------

NetBSD has many ports, and strives to maintain as much consistency as
possible between them.

One notable area of difference is the boot blocks.  There is a lot of
difference in the user API for installing or updating boot blocks, and
in many cases the boot block installation for a given port only works
when run on that platform as root, on a disk device.

Obviously different machines have different boot mechanisms, but there
should be as much consistency as possible.

In a revised scheme, we have the following requirements:
	* installboot(8) has a uniform user interface,
	  and is installed in /sbin/installboot for platforms
	  which are migrated to this new scheme.
	* installboot(8) can be run on foreign systems (other
	  NetBSD ports or even other platforms)
	* installboot(8) works on file system images as well as
	  raw devices
	* The boot blocks support various file system types as the
	  boot file system (where the kernel is found), including:
		ffs, lfs, cd9660, ustarfs
	* The boot blocks are bootable from RAIDframe mirror sets
	  (by installing the boot blocks on the underlying components)

In this paper, terms like "machine", "port", and "architecture" may be
used interchangebly, as will "PROM" and "BIOS".


2. Preferred operation of boot blocks
-------------------------------------

The boot blocks comprise of loading the following items in sequence:

    Stage 0 boot block (the first sector)
    -------------------------------------

The PROM reads the first sector of the file system.

Depending upon the platform, the first sector might contain code
which will be executed at a specific relative offset (e.g., i386),
or it might contain a list of sector offsets/counts which the PROM
then uses to read in more code to boot in (e.g., pmax).

This loads the stage 1 boot block from a hard-coded location (which
might be changed by the installboot program).

It is possible to support multiple ports booting from the same
stage 0 boot block by carefully constructing the layout of the
boot block and installing the stage 1 boot block in different
locations in the file systme.  This feature is mostly used when
constructing iso9660 CDs that can boot on multiple ports.
In this case, installboot(8) needs a flag to in-situ update the
relevant parts of the stage 0 boot block without modifying the
rest of it.

Existing use of Stage 0 (the first sector):

	Offset	Size	Machine	Use
	------	----	-------	---
	0	512	i386	MBR boot sector

	2	6	vax	boot info

	8	24	pmax	boot info

	32	440	pmax	extra program boot sections (if mode == 1)

	64	276	alpha	disklabel
			pmax	disklabel
			vax	disklabel

	128	276	sparc	disklabel
	128	276	sparc64	disklabel

	340	24	vax	boot info (more)

	480	24	alpha	boot info

	504	8	alpha	64bit checksum of previous 504 bytes

	508	4	i386	0xAA55


    Stage 1 boot block
    ------------------

Almost all platforms need extra code to support reading in the
stage 2 boot block (the ordinary file "/boot") from an arbitrary
block location on the first partition in file system that the
stage 0 boot block is installed in.  This is achieved with a stage
1 boot block which understands how to read the file system.

All NetBSD-bootable filesystems support a boot block area in
first few kilobytes (usually 8 KB).  Depending upon the port,
the disklabel is up to one sector in size and is stored somewhere
within this region.  The stage 1 boot block can be stored in
the remaining space (e.g, 7 KB).

It may be necessary to supply a separate stage 0 / stage 1
combination for each file system type that the stage 2 boot
block may be loaded from.

Stage 1 can support booting from RAIDframe mirror sets by
detecting that the first partition is type `RAID', and
making the appropriate adjustments to find the real file
system type.


    Stage 2 boot block
    ------------------

This stage is often installed as the regular file "/boot" in
the top level of the boot file system.  It provides the user
interface to the user which allows for the selection of
different file systems and kernels to boot, etc.

In order to share root file systems amongst multiple platforms,
the stage 1 boot block should search for "/boot.${MACHINE}"
before "/boot".


    Kernel
    ------

Also known as the "stage 3 boot block" :-)


3. installboot(8) - the boot block installation tool
----------------------------------------------------

installboot(8) installs the stage 0 and stage 1 boot blocks
into a file system, which may be a file or raw device.
It is found in /sbin/installboot.

installboot has the following usage:
	installboot [-nv] [-b blockno] [-m machine] [-p password] [-t timeout]
		    file-system stage1
	installboot -c [-nv] [-m machine] disk

	file-system	file system device or image to write to
	stage1		stage 1 boot block (which might contain stage 0
			for ports which have code in stage 0)

	-b bno		block number to write stage 1 from
	-c		clear/remove boot blocks
	-m machine	installboot for machine type `machine'.
			if running on NetBSD, defaults to current machine.
	-M		"merge" changes into stage 0
	-n		do nothing
	-p password	password for 2nd stage (optional support)
	-t timeout	timeout for 2nd stage (optional support)
	-v		verbose

It may not be possible to run installboot on a device that is a
component of a mounted file system (e.g., running a NetBSD system
at securelevel == 1; c.f., init(8)).  In this case, installboot
needs a method of changing the necessary blocks via the kernel
(e.g., an ioctl(2)), and that will most likely only work on a
"native" system.


[ XXX: consider port specific options via -o ? ]


4. Existing situation
---------------------

* alpha
	- stage 0 contains sector map to stage 1, and disklabel
	- separate stage 1 for ffs, ext2fs, lfs
	- stage 1 can read /boot from anywhere in the file system
	- stage 2 must exist in the first partition
	- first partition has to start at the sector 0
	- can boot off RAIDframe
    todo:
	- stage 1: tar (to replace installboot.old and bootxx.old,
	  which are used to install bootxx.old at block 17 of a
	  tarfile for floppy boot blocks.

* i386
	- stage 1 supports ffs
	- stage 1 has hard-coded block locations for stage 2
	- all components of the boot blocks and kernel must
	  reside below 8 GB (PC BIOS limit)
	- can boot off RAIDframe with significant effort and separate
	  non-mirrored partition for /boot
    todo:
	- stage 1 ffs should search for stage 2 (no hard coded blocks)
	- stage 1: lfs, cd9660, tar

* pmax
	- stage 0 is a single sector offsets/count but the firmware
	  can handle multiple discontiguous offsets/count pairs
	- separate stage 1 for ffs, ext2fs, lfs
	- stage 1 can read /boot from anywhere in the file system
	- stage 2 must exist in the first partition
	- first partition has to start at the sector 0
	- can boot off RAIDframe
	- no ustarfs, but no floppy support either
    possible todo:
	- stage 1: tar
	- floppy boot

* vax
	[similar to alpha and pmax ?]

[ XXX: fill in the missing ports ]

--- cut here ---