[comp.sys.nsc.32k] Proposal/suggestion for boot sequence

david@bacchus.oz.au (David Burren [Athos]) (09/20/90)

This is what might be called a "pc532 RFC" :-)

The problem:
	With multiple hosts on a single SCSI buss, the question arises as
	to where each should obtain a boot image from.  Each host is not
	necessarily a PC532.
	eg. I have a 68070 board that I want to put in my PC532 system.

The answers:
	I outline here a possible (admittedly incomplete) solution to this.
	If you know of an already-proposed/implemented solution, please
	speak up!

Assign each host model a unique identifier.  Using this host-ID, search
through available SCSI devices until we find a boot image for it.

The first problem is to find a SCSI ID on the buss that is willing to let us
boot.  This may be as simple as scanning all IDs through 0 up to 7 (skipping
our own ID) until an image is found.  If unsuccessful, sleep for a while and
then try again, skipping IDs that responded but didn't have an image for us.

In my example proto-code below, "id" may refer to just a SCSI ID, or a
controller/ID/LUN set.


Given a drive to search for an image, we start at a specified block on the
disk.  Ideally this block should be at the start of the disk, immediately
after any SCSI label information.
Or maybe we examine the disk geometry and pick up the last block on the drive?


The block contains an directory of the boot images available on this drive.
Each directory entry has 4 elements:

	image_id:	Identifier of the image.  This is compared against
			the host's ID.
	first_block:	Starting address of the image on the disk.
	num_blocks:	Length of the image.
	load_address:	Where in memory this image should be loaded.

If no match is found in the first block of the directory, the next consecutive
block is loaded and the process repeated.

An entry with an image_id of 0 indicates the end of the directory.

An image_id of 0xffffffff indicates the end of this directory block.
The "first_block" element of the entry is used as the address of the next
block of the directory.

Thus 0 and 0xffffffff are reserved host-IDs.

Summary:
	This system involves the reservation of one block address on all
	SCSI disks (at least in PC532 systems) and the allocation of unique
	host-IDs.
	Someone should act as a registry of host-IDs.  If we decide to go
	with this, I'm prepared to do this for now.

	The only change that most people's PC532 systems will require to be
	compliant with this is to make sure that the specified disk block
	is free, with the first four bytes set to zero.  The current method
	of "hand-booting" machines via the monitor is not interfered with.

	However, I'm hoping that this system (or one like it) will be
	incorporated in any future ROMs that have auto-booting.

The exact policy of matching host-ID against image_id may be more complex
than shown here, but if we agree on a block address now then we can get on
with the more detailed design.

A possibility is to have 24-bit host-IDs, with the image_id having 8 bits
of "version" information, with version 0 being the "generic" version.
The boot sequence would then be to search the directory for all versions
and then decide.
Maybe the version indicates which OS is in the image?

Also, if the SCSI drivers in our OSes will be able to handle being
addressed as targets, a bit of smarts behind them can make them appear
as a block device.
The idea here is to allow disk-less PC532s (and others) boot from a buss
that doesn't have any directly-connected drives, such as the PC532's 8490
buss.

With drivers able to be addressed as targets, we can use this to provide
network traffic over SCSI.
I have a large set of notes I've been making on this for IP and Amoeba
traffic, including my explorations of the SCSI driver on Sonys (almost
straight 4.3BSD).  But I won't go on about that right now.

Incidentally, the 68070 board I mentioned is the I/O processor for Simon
Burge's 34010 grey-scale card design.

Please give me your reactions on this proposal.
I may have missed something obvious, and you may have better ideas than me
about some of this.

Finally, is anyone aware of anything happening in the SCSI committee(s) to
address this or a related problem?

Thanks.
__________________________________________________________________________
David Burren                               Net:   david@bacchus.esa.oz.au
Software Development Engineer              Phone: +61 3 819 4554
Expert Solutions Australia                 Also:  athos%eyrie@labtam.oz.au


------# Example code in case I didn't describe it properly #---------------

/*
 *	NOTE:
 *	     This code assumes host-byte-order longs, and is thus incomplete.
 *	     A common byte-order should be agreed on for the directory.
 *	     (inet network byte-order?)
 */

struct index_st
{
	unsigned long	image_id;	/* Host-ID of this image.	*/
	unsigned long	first_block;	/* Where the image starts.	*/
	unsigned long	num_blocks;	/* Length of the image.		*/
	unsigned long	load_address;	/* A hint as to where in memory	*/
					/* this image should be loaded.	*/
}

#define	INDICES_PER_BLOCK	(512 / sizeof(struct index_st))

int
find_boot_image(my_id, id, answer)
	unsigned long		my_id;		/* My host-ID.		*/
	int		id;		/* Which drive to search.	*/
	struct index_st	*answer;
{
	struct index_st	block[INDICES_PER_BLOCK];
	unsigned long	location = MAGIC_ADDR;	/* This is the location that */
						/* needs to be agreed upon.  */
	int	index;

loop:	/* Argh!  A "goto" label! :-) */

	if (scsi_read(id, location, &block) == -1)
	{
		/*
		 *	Drive presumeably didn't respond.
		 */
		return(-1);
	}
	for (index = 0; index < INDICES_PER_BLOCK; index++)
	{
		unsigned long	image_id = block[index].image_id;

		if (image_id == 0)
		{
			return(0);	/* Didn't find a boot image. */
		}
		if (image_id == 0xffffffff)
		{
			location = block[index].first_block;
			break;
		}
		if (image_id == my_id)
		{
			*answer = boot[index];
			return(1);
		}
	}
	if (index == INDICES_PER_BLOCK)
		location++;
	goto loop;
}