On Thursday, December 2, David Gwynne wrote:
> the boot loader passes a variable that identifies the disk its
> booting off made up of a bunch of fields like adapter, controller,
> disk, and partition offsets, plus a table of all the disks it can
> see which includes this id and a checksum.

Unfortunately, on the PC there is no 100% reliable mapping between the
BIOS disk number (which is used for booting), and the device path used
on the obsd side.  So in essence, we need to "find" the device we booted
from.  This was/is the point to the checksums.  At the point where the
checksum stuff was implemented, I seriously thought about sending the
checksum of the boot device through the bootdev var during boot.  With
a few "special" cases to signify network/etc style boots.  This seemed
somewhat "hackish"...

I've always wondered why the B_* defines in reboot.h were MI, as opposed
to MD.  Booting is inherantly a very MD stype of thing.  Something that
makes 100% sense on the VAX will likley map poorly or not at all to a PC
or a Sun box.  Anyways, that all aside...


> the kernel goes through and checksums the disks and then maps that
> back to the id associated with that disk, and then compares some
> of the fields in those ids against the boot disks id to figure out
> which disk its on.

Yup, and this works most of the time... unless you happen to have all
the disks zero'd or otherwise bit-identical.  :)


> the problem is we overflow one of those fields (the disk id one).
> since the other fields are set to 0 by the boot loader, this doesnt
> really matter that much. however, since those fields are now
> significant because of the overflow, we should compare them too.
> 
> this prevents sd16 being matched as the boot disk after sd0 on my
> system with 25 disks attached.
> 
> sorry if this explanation sucks.

Nope, no suck.  Makes sense.  Hackish solution, but likely the best one
for right now.  A quick egrep through /usr/src seems to indicate that
the only parts of the kernel that really care are MD parts, and nothing
really uses it in userland.  Prime candidate to re-factor someday.

> ok?
> 
> Index: dkcsum.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/amd64/dkcsum.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 dkcsum.c
> --- dkcsum.c  10 Dec 2008 23:41:19 -0000      1.15
> +++ dkcsum.c  2 Dec 2010 05:08:25 -0000
> @@ -71,10 +71,13 @@ dkcsumattach(void)
>  
>  #ifdef DEBUG
>       printf("dkcsum: bootdev=%#x\n", bootdev);
> -     for (bdi = bios_diskinfo; bdi->bios_number != -1; bdi++)
> -             if (bdi->bios_number & 0x80)
> -                     printf("dkcsum: BIOS drive %#x checksum is %#x\n",
> -                         bdi->bios_number, bdi->checksum);
> +     for (bdi = bios_diskinfo; bdi->bios_number != -1; bdi++) {
> +             if (bdi->bios_number & 0x80) {
> +                     printf("dkcsum: BIOS drive %#x bsd_dev=%#x "
> +                         "checksum=%#x\n", bdi->bios_number, bdi->bsd_dev,
> +                         bdi->checksum);
> +             }
> +     }
>  #endif
>       pribootdev = altbootdev = 0;
>  
> @@ -180,7 +183,9 @@ dkcsumattach(void)
>                */
>  
>               /* B_TYPE dependent hd unit counting bootblocks */
> -             if ((B_TYPE(bootdev) == B_TYPE(hit->bsd_dev)) &&
> +             if ((B_ADAPTOR(bootdev) == B_ADAPTOR(hit->bsd_dev)) &&
> +                 (B_CONTROLLER(bootdev) == B_CONTROLLER(hit->bsd_dev)) &&
> +                 (B_TYPE(bootdev) == B_TYPE(hit->bsd_dev)) &&
>                   (B_UNIT(bootdev) == B_UNIT(hit->bsd_dev))) {
>                       int type, ctrl, adap, part, unit;

I'm likely late to the party, but it looks ok.  And if it works, I really
can't test this... then it's ok by me.

--Toby.

Reply via email to