i386 doesn't have this bug?
> 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.
>
> 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.
>
> 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.
>
> 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;