Subject: Re: Compaq diagnostic partition Vs Bootselector
To: <>
From: David Laight <david@l8s.co.uk>
List: port-i386
Date: 01/13/2002 20:52:59
This is a multi-part message in MIME format.
--------------A933954AA24D7B00F480E96C
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Andy Ball wrote:
> 
> Hello David,
> 
>   DL> Yes, one of its few cryptic error messages...
> 
> Are it's error messages somewhat terse because it has to
> live within 512 bytes?

512 would be luxury!  Remove 4x16 for the partition table and 2 for the
55, aa at the end, the bootsel setup steals 9x4 (names), another 55aa,
two bytes timeout, flags and default key.  So 512 - 2 - 62 - 2 - 36 - 4
= 404 bytes for the code and messages.  The code also has to relocate
itself because the pbr expects to execute at the same address (0x7c00 I
think).

The version under CVS has about 2 bytes free.  My version has 37.  The
only thing I've removed is the retry loops on the disk reads.  I don't
think reads ever fail recoverably. Apart from that the functionality is
somewhat better.
> 
>   DL> That is the physical geometry (probably a lie), the
>     > BIO geometry has a max cylinders of 1023
> 
> I imagine all the geometries are fake these days :-)
They are - but that only means that there is not performance reason to
align 'cylinder groups' on cylinder boundaries.

> Perhaps FDISK was telling me what it had been told by the BIOS,
> which might account for its apparent confidence in the
> values it suggested.  That suggests that the BIOS is doing
> some geometry conversion.

fdisk normally reports two sets of values (from my disk):

  NetBSD disklabel disk geometry:
  cylinders: 16383 heads: 16 sectors/track: 63 (1008 sectors/cylinder)

  BIOS disk geometry:
  cylinders: 1023 heads: 255 sectors/track: 63 (16065 sectors/cylinder)

The top set are the 'real' values - ie they are valid limits for ATA
requests. The lower those that you need to use when comverting LBA to
CHS for BIOS reads.  The BIOS does some horrid geometry calculation
(probably via an LBA sector number).

> 
>   DL> That isn't the bootselecter, that is the netbsd 'boot'
>     > program.  It is loaded out of the netbsd root
>     > partition.  It will only load netbsd (r something very
>     > similar). But will do from any disk it knows of.
> 
> I forget the wording that sysinst used, but could tell that
> it was the ordinary boot sector.  It seems a good, no-
> nonsense way to bring the machine up.

No - there is a second piece of code that sysinst will put into the
mbr.  It does the same job as the mbr_bootsel code, but always reads a
fixed partitions pbr (probably the 'active' one).  The bootselect code
does the same job and more.  The mbr code (fdisk/mbr) could be deleted
in favour of the mbr_bootselect code - if anyone was willing to assume
responsibility.
> 
>   DL> The bootselecter sits completely within the mbr
>     > (sector 0), it will (probbaly) boot most os that will
>     > boot from standard mbr code.  Quite useful if you want
>     > to multiboot a system.
> 
> Possibly also useful if I want to test different kernels and
> boot devices?

Boot devices in the sense that it will read the mbr from a different
disk, different kernels only if they are in different partitions.
> 
>   DL> Anyone one to do some further tests for me?
> 
> I'll happily do that.  I have another ProLinea that I can
> use as a test-bed, and I'll happily donate some time to help
> out.

A second system!  I'm testing the mbr a single system.....  
> 
> I'll try to replicate my situation on that machine: diag
> partition and NetBSD 'part of disk' that's installed, but
> won't boot.  That should give me the opportunity to check
> out your improvements.  Where do I find the source?

On my system....
I've attached a diff of sbin/fdisk/fdisk.c (from 1.5.2ish sources) and
the sbin/fdisk/mbr_bootsel/mbr_bootsel binary (too small for a trojan)
to this email.  You don't need the new fdisk, but it is hard to update
the mbr_bootsel code without it (it only loads the bootsel code from the
s/usr/mdec, and only if it is not installed).
'fdisk -i -c mbr_boolsel' will work if you update fdisk

	David
--------------A933954AA24D7B00F480E96C
Content-Type: text/plain; charset=us-ascii;
 name="fdisk.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="fdisk.diff"

606d605
< 	int copy_size =  sizeof(mboot.bootinst);
609,615c608
< 	if (!bootsize) {
< #ifdef __i386__
< 	    if (B_flag)
< 		bootsize = read_boot(DEFAULT_BOOTSELCODE, bootcode,
< 		    sizeof bootcode);
< 	    else
< #endif
---
> 	if (!bootsize)
618,625d610
< 	}
< #endif
< #ifdef __i386__
< 	if (((struct mbr_bootsel *)&mboot.bootinst[MBR_BOOTSELOFF])->magic ==
< 								MBR_MAGIC 
< 		&& ((struct mbr_bootsel *)&bootcode[MBR_BOOTSELOFF])->magic ==
< 								 MBR_MAGIC)
< 	    copy_size = MBR_BOOTSELOFF;
628c613
< 	memcpy(mboot.bootinst, bootcode, copy_size);
---
> 	memcpy(mboot.bootinst, bootcode, sizeof(mboot.bootinst));
758,762c743,744
< 		/* read default bootselect code unless we already have one */
< 		if (!bootsize || ((struct mbr_bootsel *)&bootcode
< 				[MBR_BOOTSELOFF])->magic != MBR_MAGIC)
< 			bootsize = read_boot(DEFAULT_BOOTSELCODE, bootcode,
< 				sizeof bootcode);
---
> 		bootsize = read_boot(DEFAULT_BOOTSELCODE, bootcode,
> 		    sizeof bootcode);
767,770d748
< 		/* If bootfile was specified with -c, copy it in */
< 		if (bootsize && ((struct mbr_bootsel *)&bootcode
< 				[MBR_BOOTSELOFF])->magic == MBR_MAGIC)
< 			memcpy(mboot.bootinst, bootcode, MBR_BOOTSELOFF);
871,874c849
< 	/* ticks are probably 64k/3600 - so our long timers are sligtly
< 	   out!  newer bootcode always waits for 1 tick, so treats 0xffff
< 	   as wait forever. */
< 	timo = mbs->timeo == 0xffff ? -1 : (10 * mbs->timeo + 9) / 182;
---
> 	timo = ((1000 * mbs->timeo) / 18200);
876,878c851,853
< 		decimal("Timeout value (seconds, -1 => never)", &timo);
< 	} while (timo < -1 || timo > 3600);
< 	mbs->timeo = timo == -1 ? 0xffff : (timo * 182) / 10;
---
> 		decimal("Timeout value", &timo);
> 	} while (timo < 0 || timo > 3600);
> 	mbs->timeo = (u_int16_t)((timo * 18200) / 1000);
908,909d882
< 	/* scan active partitions to see if we need LBA reads */
< 	mbs->flags &= ~BFL_EXTINT13;

--------------A933954AA24D7B00F480E96C
Content-Type: application/octet-stream;
 name="mbr_bootsel"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="mbr_bootsel"

McCO0LwAfAAAjsCO2InmvwAGuQAB86XqHAYAAID6gHIFgPqHdgKygFKglQeoAXRqv5gHsDGA
PQB0FKJbB75aB+j5AIn+6PQAvlcH6O4A/sCDxwk8NXXeMOTNGonXtAHNFnUSMOTNGin6oZYH
OcJ27aCUB+sGMOTNFojgPBx0Gyw7PAN2OSwEOgZ1BHMJvl8HBIBaUOt8sD/rEr6+B7kEAIA8
gHQ0g8YQ4vawMaJWB75QB+iHAMcGlgf//+ly/76uB7+PB4PGEIPHCSwBc/aIRAT2JYXAsHB0
01pSVrQIzRNeweoIQmYxwIjIJD/34maRwOgGhsRAZphm9+Fmi1wIZjnYdw6+XwdmiVwItEJa
6w/rmlqKdAGLTAK7AHy4AQJSVs0TXrAycuih/n09VaqwM3XeZot0CFrqAHwAAFCshMB0BegE
AOv2WMO0DrMHzRDDRXJyb3IgeA0KAEYxOiAAEAABAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAbYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAVaoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVao=
--------------A933954AA24D7B00F480E96C--