Subject: Re: Hardware detection and custom kernel build
To: NetBSD kernel list <tech-kern@NetBSD.org>
From: Thierry Laronde <tlaronde@polynum.com>
List: tech-kern
Date: 03/07/2004 17:39:48
Hello,

Thanks for the tips.

I have tried to find a fixed point allowing the description of what is
bootloading stuff and what is not, since, as mentionned by Martin 
Husemann, depending on the architecture the firmware can provide a i
different amount of "code" (drivers) to the kernel, hence the 
definition and the size of the bootloader vary greatly, and as 
mentionned by Matthew Orgass, there may be some incentive not to start 
from scratch (hardware bootstrap) when one wants to change the "kernel",
and there is some reasons to try allow the "kernel" to be used as a 
bootloader.

I have finally come with the following theoretical definitions which, at
least for me, seem to make some sense and will allow to reformulate the
implementation of what I'm after (mainly replacing GNU GRUB and
etherboot with NetBSD code). Comments are more welcome than ever!

kernel == sum of _all_ the actual software used to control the hardware
usage
	=> this may include code found in dedicated places in the hardware
	(ROM, i.e firmware)

There are two main blocks in the kernel:

1) code to drive the hardware
2) code to enforce a usage policy of the hardware resources

The descriptions of the Unix system as found in M.J Bach's book
typically address part 2. It can make sense to call the part 1 the
bootstrapping procedure since "process 0 is created by hand" that is is
bootstrapped too.

A simplified bottom-up description could be the following:


	_______________________________
	|                              |            /\
	|                              |
	|    Multi-task                |           PART 2
	|    Multi-user,               |        Kernel Evolution
	|    ...                       |
	|                              |
	|                              |            \/
	--------------------------------------------- Ground 0
	|     Hardware configuration   |__          /\
	--------------------------------  |
	|           ...                |  |
	--------------------------------  |
	|       Driver loading         |  |        PART 1
	--------------------------------  |     "Primitive" Kernel
	|       Driver loading         |/_|
	--------------------------------\
	| Hardware bootstrap procedure |            \/
	--------------------------------------------- Chaos

Here "Primitive" is not to be taken in a pejorative sense. 

Note: MS-DOS was, for example, an OS almost restricted to the primitive
kernel with a huge part of the drivers provided by the firmware.

Definition:

bootloader == subset of the primitive kernel consisting of the hardware
	bootstrap procedure, a non empty subset of drivers, and a possibly
	empty subset of hardware configuration abilities

So we can have a bootloader that is exactly the primitive kernel, going
"kloader", if I understand correctly, meaning returning to ground 0 and
loading another kind of "kernel evolution".

If we continue in such a scheme, we can "deduce" the following
characteristics of what could be needed at the hardware configuration
stage (ground 0):

1) Ability to load/unload drivers -> going autoconf is partly already
that ; but perhaps the network stuff (BOOTP/DHCP
discover (for network cards EPROM) could be at this stage, meaning too
the ability to retrieve additionnal drivers via UDP/IP)

2) At this stage there should be two users and only two: the kernel root
user and the not_kernel_root_user. The kernel root user has his password
stored in the primitive kernel. The not_kernel_root_user has no ability
to change the list of hardware managed but only the possibility to
select options already defined by the kernel root user (menu) --- and
since the not_kernel_root_user is exactly what he is, he has no password
;

3) Can we imagine that the root '/' is indeed inside the memory image of
the primitive kernel (a pseudo fs) meaning that doing a `ls' at this
stage will lead:
	/kernfs
	/dev [devices detected and allowed]
	/kbin [kernel programs i.e. (not absolutely true) kernel threads]

[Hence, this is consistent with the kernel root's password stored in the
primitive kernel since it's, too, the fs :-^ ]

4) The users interact with the primitive kernel via the kernel shell
(autoconf prompt is something like that). And the "programs" are not
external ones but in kernel ones (this simplifies the ABI).

5) At ground 0 there is the ability to mount an external root fs, and to
load a kernel, whether part 2 or another one that will totally or partly
replace the primitive kernel (chainloading).

Does this make sense? And if yes, to come back to my initial post:

Is there a practical way to segregate part I from part II, that is to
compile the "hardware bootstrapping", some drivers, hardware
configuration in order to create a primitive kernel used as a bootloader
(meaning the ability to use NetBSD sources to compile code to put in
network cards EPROM, and the ability to achieve more than is actually
done with other bootloaders)?

TIA.
-- 
Thierry Laronde (Alceste) <tlaronde@polynum.org>
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C