Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Move mbr_bootsel from offset 404 to offset 400 in struct mbr...



details:   https://anonhg.NetBSD.org/src/rev/99647dd9c880
branches:  trunk
changeset: 559688:99647dd9c880
user:      lukem <lukem%NetBSD.org@localhost>
date:      Mon Mar 22 07:11:00 2004 +0000

description:
Move mbr_bootsel from offset 404 to offset 400 in struct mbr_sector to
leave 4 bytes for the Windows NT Drive Serial Number (DSN) at 440-443
(as mbr_sector.mbr_dsn).

Ensure that all the MBR & PBR code reserves space for mbr_sector.mbr_dsn.

Leave the bootsel magic number at 444-445 as mbr_sector.mbr_bootsel_magic
(instead of mbr_sector.mbr_bootsel.mbrbs_magic), but use 0xb5e1 (MBR_BS_MAGIC)
instead of 0xaa55 (MBR_MAGIC) to indicate that this change has occurred.

Rework MBR_BS_NEWMBR to mean "mbr_bootsel has moved to 400".

Modify fdisk(8) to automatically relocate the mbr_bootsel from 404 to 400
if mbr_bootsel_magic is the old value (0xaa55), and unset MBR_BS_NEWMBR
to flag that new mbr_bootsel code must be used if updating the MBR.


These changes fixes a problem where Windows 2000 or Windows XP would corrupt
the last 3 bytes + NUL of MBR partition 3's bootsel name if the bootsel name
was 5 characters long, replacing bytes 6-9 with the DSN.
Also, by explicitly reserving the space for the DSN we prevent problems in the
future if non bootsel MBR or PBR code had other information at bytes 440-443.

diffstat:

 distrib/utils/sysinst/arch/i386/md.c |   15 +---
 distrib/utils/sysinst/mbr.c          |   10 +-
 sbin/fdisk/fdisk.c                   |  105 ++++++++++++++++++++---------------
 sys/arch/i386/stand/bootxx/pbr.S     |   12 +++-
 sys/arch/i386/stand/mbr/mbr.S        |   24 ++++++--
 sys/sys/bootblock.h                  |   27 ++++++---
 6 files changed, 116 insertions(+), 77 deletions(-)

diffs (truncated from 549 to 300 lines):

diff -r f03a75e2b473 -r 99647dd9c880 distrib/utils/sysinst/arch/i386/md.c
--- a/distrib/utils/sysinst/arch/i386/md.c      Mon Mar 22 05:25:22 2004 +0000
+++ b/distrib/utils/sysinst/arch/i386/md.c      Mon Mar 22 07:11:00 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: md.c,v 1.99 2003/11/30 14:36:45 dsl Exp $ */
+/*     $NetBSD: md.c,v 1.100 2004/03/22 07:11:00 lukem Exp $ */
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -167,13 +167,14 @@
                bootcode = _PATH_MBR;
 
        /* Look at what is installed */
-       if (mbr.mbr.mbr_bootsel.mbrbs_magic == htole16(MBR_MAGIC))
+       if (mbr.mbr.mbr_bootsel_magic == htole16(MBR_BS_MAGIC))
                /* Netbsd bootcode, grab its features */
                ofl = mbr.mbr.mbr_bootsel.mbrbs_flags;
        else {
                /* Not netbsd code, might be ok if we are booting the active
                 * partition.
                 */
+/* XXXLUKEM: unconditionally set ofl=0 with new bootsel code? */
                if (mbr.mbr.mbr_magic == htole16(MBR_MAGIC) &&
                    mbr.mbr.mbr_jmpboot[0] != 0 &&
                    (fl & (MBR_BS_ACTIVE | MBR_BS_EXTLBA)) == 0 &&
@@ -229,17 +230,11 @@
        }
        close(fd);
 
-       if (new_mbr.mbr_bootsel.mbrbs_magic != htole16(MBR_MAGIC))
+       if (new_mbr.mbr_bootsel_magic != htole16(MBR_BS_MAGIC))
                return -1;
 
-       if (mbrs->mbr_bootsel.mbrbs_magic == htole16(MBR_MAGIC)) {
+       if (mbrs->mbr_bootsel_magic == htole16(MBR_BS_MAGIC)) {
                len = offsetof(struct mbr_sector, mbr_bootsel);
-               if (!(mbrs->mbr_bootsel.mbrbs_flags & MBR_BS_NEWMBR))
-                       /*
-                        * Meaning of keys has changed, force a sensible
-                        * default (old code didn't preseve the answer).
-                        */
-                       mbrs->mbr_bootsel.mbrbs_defkey = SCAN_ENTER;
        } else
                len = offsetof(struct mbr_sector, mbr_parts);
 
diff -r f03a75e2b473 -r 99647dd9c880 distrib/utils/sysinst/mbr.c
--- a/distrib/utils/sysinst/mbr.c       Mon Mar 22 05:25:22 2004 +0000
+++ b/distrib/utils/sysinst/mbr.c       Mon Mar 22 07:11:00 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mbr.c,v 1.58 2004/01/18 16:27:25 dsl Exp $ */
+/*     $NetBSD: mbr.c,v 1.59 2004/03/22 07:11:00 lukem Exp $ */
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -1369,13 +1369,13 @@
                }
 #if BOOTSEL
                else {
-                       if (mbrs->mbr_bootsel.mbrbs_magic == htole16(MBR_MAGIC))
+                       if (mbrs->mbr_bootsel_magic == htole16(MBR_BS_MAGIC))
                                bootkey = mbrs->mbr_bootsel.mbrbs_defkey;
                        else
                                bootkey = 0;
                        bootkey -= SCAN_1;
                }
-               if (mbrs->mbr_bootsel.mbrbs_magic == htole16(MBR_MAGIC))
+               if (mbrs->mbr_bootsel_magic == htole16(MBR_BS_MAGIC))
                        memcpy(mbri->nametab, mbrs->mbr_bootsel.mbrbs_nametab,
                                sizeof mbri->nametab);
 #endif
@@ -1483,14 +1483,14 @@
         * copy in all the menu strings and set the default keycode
         * to be that for the default partition.
         */
-       if (mbri->mbr.mbr_bootsel.mbrbs_magic == htole16(MBR_MAGIC)) {
+       if (mbri->mbr.mbr_bootsel_magic == htole16(MBR_BS_MAGIC)) {
                int8_t key = SCAN_1;
                mbri->mbr.mbr_bootsel.mbrbs_defkey = SCAN_ENTER;
                for (ext = mbri; ext != NULL; ext = ext->extended) {
                        mbrs = &ext->mbr;
                        mbrp = &mbrs->mbr_parts[0];
                        /* Ensure marker is set in each sector */
-                       mbrs->mbr_bootsel.mbrbs_magic = htole16(MBR_MAGIC);
+                       mbrs->mbr_bootsel_magic = htole16(MBR_BS_MAGIC);
                        /* and copy in menu strings */
                        memcpy(&mbrs->mbr_bootsel.mbrbs_nametab, &ext->nametab,
                            sizeof mbrs->mbr_bootsel.mbrbs_nametab);
diff -r f03a75e2b473 -r 99647dd9c880 sbin/fdisk/fdisk.c
--- a/sbin/fdisk/fdisk.c        Mon Mar 22 05:25:22 2004 +0000
+++ b/sbin/fdisk/fdisk.c        Mon Mar 22 07:11:00 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fdisk.c,v 1.75 2004/03/19 18:19:17 dyoung Exp $ */
+/*     $NetBSD: fdisk.c,v 1.76 2004/03/22 07:11:00 lukem Exp $ */
 
 /*
  * Mach Operating System
@@ -35,7 +35,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: fdisk.c,v 1.75 2004/03/19 18:19:17 dyoung Exp $");
+__RCSID("$NetBSD: fdisk.c,v 1.76 2004/03/22 07:11:00 lukem Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -635,8 +635,9 @@
                }
 #ifdef BOOTSEL
                if (!sh_flag &&
-                   le16toh(mboot.mbr_bootsel.mbrbs_magic) == MBR_MAGIC){
+                   le16toh(mboot.mbr_bootsel_magic) == MBR_BS_MAGIC) {
                        int tmo;
+
                        printf("Bootselector ");
                        if (mboot.mbr_bootsel.mbrbs_flags & MBR_BS_ACTIVE) {
                                printf("enabled");
@@ -746,7 +747,7 @@
 
        printf("%s (sysid %d)\n", get_type(partp->mbrp_type), partp->mbrp_type);
 #ifdef BOOTSEL
-       if (le16toh(boot->mbr_bootsel.mbrbs_magic) == MBR_MAGIC &&
+       if (le16toh(boot->mbr_bootsel_magic) == MBR_BS_MAGIC &&
            boot->mbr_bootsel.mbrbs_nametab[part][0])
                printf("%*s    bootmenu: %s\n", indent, "",
                    boot->mbr_bootsel.mbrbs_nametab[part]);
@@ -851,7 +852,7 @@
        /*
         * Do some sanity checking here
         */
-       if (le16toh(bootcode[0].mbr_magic) != MBR_MAGIC) {
+       if (le16toh(((struct mbr_sector *)buf)->mbr_magic) != MBR_MAGIC) {
                warnx("%s: invalid magic", boot_path);
                goto fail;
        }
@@ -868,7 +869,7 @@
 }
 
 void
-init_sector0(int dopart)
+init_sector0(int zappart)
 {
        int i;
        int copy_size =  MBR_PART_OFFSET;
@@ -879,9 +880,9 @@
                        sizeof bootcode, 1);
 #endif
 #ifdef BOOTSEL
-       if (le16toh(mboot.mbr_bootsel.mbrbs_magic) == MBR_MAGIC 
-           && le16toh(bootcode[0].mbr_bootsel.mbrbs_magic) == MBR_MAGIC)
-               copy_size = MBR_BOOTSEL_OFFSET;
+       if (le16toh(mboot.mbr_bootsel_magic) == MBR_BS_MAGIC 
+           && le16toh(bootcode[0].mbr_bootsel_magic) == MBR_BS_MAGIC)
+               copy_size = MBR_BS_OFFSET;
 #endif
 
        if (bootsize != 0) {
@@ -890,7 +891,7 @@
        }
        mboot.mbr_magic = htole16(MBR_MAGIC);
        
-       if (!dopart)
+       if (!zappart)
                return;
        for (i = 0; i < MBR_PART_COUNT; i++)
                memset(&mboot.mbr_parts[i], 0, sizeof(mboot.mbr_parts[i]));
@@ -1051,7 +1052,7 @@
        uint id;
        int p;
 
-       if (le16toh(mboot.mbr_bootsel.mbrbs_magic) != MBR_MAGIC)
+       if (le16toh(mboot.mbr_bootsel_magic) != MBR_BS_MAGIC)
                /* default to first active partition */
                return DEFAULT_ACTIVE;
 
@@ -1059,16 +1060,6 @@
                return DEFAULT_ACTIVE;
                
        id = mboot.mbr_bootsel.mbrbs_defkey;
-       if (!(mboot.mbr_bootsel.mbrbs_flags & MBR_BS_NEWMBR)) {
-               /* F1..F4 => ptn 0..3, F5+ => disk 0+ */
-               id -= SCAN_F1;
-               if (id >= MBR_PART_COUNT)
-                       /* Return number of disk */
-                       return id - MBR_PART_COUNT;
-               if (mboot.mbr_parts[id].mbrp_type != 0)
-                       return le32toh(mboot.mbr_parts[id].mbrp_start);
-               return DEFAULT_ACTIVE;
-       }
 
        /* 1+ => allocated partition id, F1+ => disk 0+ */
        if (id >= SCAN_F1)
@@ -1103,7 +1094,7 @@
        int p;
        int key = SCAN_1;
 
-       if (le16toh(mboot.mbr_bootsel.mbrbs_magic) != MBR_MAGIC)
+       if (le16toh(mboot.mbr_bootsel_magic) != MBR_BS_MAGIC)
                /* sanity */
                return;
 
@@ -1118,10 +1109,7 @@
                if (mboot.mbr_bootsel.mbrbs_nametab[p][0] == 0)
                        continue;
                if (le32toh(mboot.mbr_parts[p].mbrp_start) == default_ptn) {
-                       if (mboot.mbr_bootsel.mbrbs_flags & MBR_BS_NEWMBR)
-                               mboot.mbr_bootsel.mbrbs_defkey = key;
-                       else
-                               mboot.mbr_bootsel.mbrbs_defkey = SCAN_F1 + p;
+                       mboot.mbr_bootsel.mbrbs_defkey = key;
                        return;
                }
                key++;
@@ -1143,10 +1131,7 @@
        }
 
        if (default_ptn < 8) {
-               if (mboot.mbr_bootsel.mbrbs_flags & MBR_BS_NEWMBR)
-                       key = SCAN_F1;
-               else
-                       key = SCAN_F1 + 4;
+               key = SCAN_F1;
                mboot.mbr_bootsel.mbrbs_defkey = key + default_ptn;
                return;
        }
@@ -1163,11 +1148,13 @@
        int ext13 = 0;
        char *code;
 
+       needed |= MBR_BS_NEWMBR;        /* need new bootsel code */
+
        /* Work out which boot code we need for this configuration */
        for (p = 0; p < MBR_PART_COUNT; p++) {
                if (mboot.mbr_parts[p].mbrp_type == 0)
                        continue;
-               if (le16toh(mbs->mbrbs_magic) != MBR_MAGIC)
+               if (le16toh(mboot.mbr_bootsel_magic) != MBR_BS_MAGIC)
                        break;
                if (mbs->mbrbs_nametab[p][0] == 0)
                        continue;
@@ -1177,7 +1164,7 @@
        }
 
        for (p = 0; p < ext.num_ptn; p++) {
-               if (le16toh(ext.ptn[p].mbr_bootsel.mbrbs_magic) != MBR_MAGIC)
+               if (le16toh(ext.ptn[p].mbr_bootsel_magic) != MBR_BS_MAGIC)
                        continue;
                if (ext.ptn[p].mbr_parts[0].mbrp_type == 0)
                        continue;
@@ -1190,7 +1177,8 @@
                needed |= MBR_BS_ACTIVE;
 
        /* Is the installed code good enough ? */
-       if (!i_flag && (needed == 0 || (le16toh(mbs->mbrbs_magic) == MBR_MAGIC
+       if (!i_flag && (needed == 0 ||
+           (le16toh(mboot.mbr_bootsel_magic) == MBR_BS_MAGIC
            && (mbs->mbrbs_flags & needed) == needed))) {
                /* yes - just set flags */
                mbs->mbrbs_flags |= ext13;
@@ -1206,12 +1194,13 @@
 
        if (!f_flag && bootsize == 0)
                /* Output an explanation for the 'update bootcode' prompt. */
-               printf("Installed bootfile doesn't support required options.\n");
+               printf("\n%s\n",
+                   "Installed bootfile doesn't support required options.");
 
        /* Were we told a specific file ? (which we have already read) */
        /* If so check that it supports what we need. */
        if (bootsize != 0 && needed != 0
-           && (le16toh(bootcode[0].mbr_bootsel.mbrbs_magic) != MBR_MAGIC
+           && (le16toh(bootcode[0].mbr_bootsel_magic) != MBR_BS_MAGIC
            || ((bootcode[0].mbr_bootsel.mbrbs_flags & needed) != needed))) {
                /* No it doesn't... */
                if (f_flag)
@@ -1251,7 +1240,7 @@
 
        init_sector0(0);
 
-       if (le16toh(mbs->mbrbs_magic) == MBR_MAGIC)
+       if (le16toh(mboot.mbr_bootsel_magic) == MBR_BS_MAGIC)
                mbs->mbrbs_flags = bootcode[0].mbr_bootsel.mbrbs_flags | ext13;
 }
 
@@ -1758,7 +1747,7 @@
                strlcpy(tmp_bootmenu, bootmenu, bootmenu_len);
        else
                if (boot != NULL &&
-                   le16toh(boot->mbr_bootsel.mbrbs_magic) == MBR_MAGIC)
+                   le16toh(boot->mbr_bootsel_magic) == MBR_BS_MAGIC)
                        strlcpy(tmp_bootmenu,
                                boot->mbr_bootsel.mbrbs_nametab[upart],
                                bootmenu_len);
@@ -1946,7 +1935,7 @@
                if (start == 0 && size == 0)
                        memset(partp, 0, sizeof *partp);
 #ifdef BOOTSEL
-               if (le16toh(boot->mbr_bootsel.mbrbs_magic) == MBR_MAGIC)
+               if (le16toh(boot->mbr_bootsel_magic) == MBR_BS_MAGIC)
                        memset(boot->mbr_bootsel.mbrbs_nametab[upart], 0,
                                sizeof boot->mbr_bootsel.mbrbs_nametab[0]);



Home | Main Index | Thread Index | Old Index