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; }