bin/127764: Patch to preserve NT disk UID data for boot0cfg
Daniel J. O'Connor
darius at midget.dons.net.au
Wed Oct 1 06:30:02 UTC 2008
>Number: 127764
>Category: bin
>Synopsis: Patch to preserve NT disk UID data for boot0cfg
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Oct 01 06:30:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator: Daniel J. O'Connor
>Release: FreeBSD 8.0-CURRENT i386
>Organization:
>Environment:
-current as of 1/Oct/08.
>Description:
boot0/boot0cfg currently overwrite the NT UID in the MBR which causes MS
Windows Vista to fail to boot (unless you follow instructions here
http://www.clearchain.com/wiki/FreeBSD_&_Windows_Vista), it can also confuse
MS Windows XP.
Eugene Grosbein wrote patches and posted them here..
http://groups.google.ru/group/fido7.ru.unix.bsd/browse_thread/thread/dbb7ee5ebc159f73/8dab84b83e46ab84?hl=ru&fwc=2
I'd like them committed as they do work and I expect more people to dual boot
Vista these days..
>How-To-Repeat:
>Fix:
Index: lib/libdisk/write_i386_disk.c
===================================================================
RCS file: /usr/CVS-Repository/src/lib/libdisk/write_i386_disk.c,v
retrieving revision 1.9
diff -u -r1.9 write_i386_disk.c
--- lib/libdisk/write_i386_disk.c 4 Jun 2004 11:49:11 -0000 1.9
+++ lib/libdisk/write_i386_disk.c 25 Jul 2007 02:04:25 -0000
@@ -75,9 +75,9 @@
if (mbrblk[0x1b0] == 0x66 && mbrblk[0x1b1] == 0xbb) {
if (edd)
- mbrblk[0x1bb] |= 0x80; /* Packet mode on */
+ mbrblk[0x1af] |= 0x80; /* Packet mode on */
else
- mbrblk[0x1bb] &= 0x7f; /* Packet mode off */
+ mbrblk[0x1af] &= 0x7f; /* Packet mode off */
}
}
@@ -94,6 +94,11 @@
int s[4];
int need_edd = 0; /* Need EDD (packet interface) */
+#ifndef OFF_NTSERNUM
+#define OFF_NTSERNUM 0x1b8
+#endif
+ unsigned char ntsernum[4];
+
strcpy(device, _PATH_DEV);
strcat(device, d1->name);
@@ -108,6 +113,7 @@
}
dp = (struct dos_partition *)(mbrblk + DOSPARTOFF);
memcpy(work, dp, sizeof work);
+ memcpy(ntsernum, mbrblk + OFF_NTSERNUM, sizeof(ntsernum));
dp = work;
free(mbrblk);
for (c1 = d1->chunks->part; c1; c1 = c1->next) {
@@ -188,6 +194,7 @@
}
if (d1->bootmgr) {
memcpy(mbrblk, d1->bootmgr, DOSPARTOFF);
+ memcpy(mbrblk + OFF_NTSERNUM, ntsernum, sizeof(ntsernum));
Cfg_Boot_Mgr(mbrblk, need_edd);
}
memcpy(mbrblk + DOSPARTOFF, dp, sizeof *dp * NDOSPART);
Index: usr.sbin/boot0cfg/boot0cfg.c
===================================================================
RCS file: /usr/CVS-Repository/src/usr.sbin/boot0cfg/boot0cfg.c,v
retrieving revision 1.20
diff -u -r1.20 boot0cfg.c
--- usr.sbin/boot0cfg/boot0cfg.c 15 Jul 2005 08:04:32 -0000 1.20
+++ usr.sbin/boot0cfg/boot0cfg.c 25 Jul 2007 02:08:04 -0000
@@ -44,10 +44,11 @@
#define MBRSIZE 512 /* master boot record size */
+#define OFF_OPT 0x1ad /* offset: default boot option */
+#define OFF_DRIVE 0x1ae /* offset: setdrv drive */
+#define OFF_FLAGS 0x1af /* offset: option flags */
#define OFF_VERSION 0x1b0 /* offset: version number */
-#define OFF_OPT 0x1b9 /* offset: default boot option */
-#define OFF_DRIVE 0x1ba /* offset: setdrv drive */
-#define OFF_FLAGS 0x1bb /* offset: option flags */
+#define OFF_NTSERNUM 0x1b8 /* offset: NT Drive Serial Number */
#define OFF_TICKS 0x1bc /* offset: clock ticks */
#define OFF_PTBL 0x1be /* offset: partition table */
#define OFF_MAGIC 0x1fe /* offset: magic number */
@@ -154,15 +155,17 @@
write_mbr(fpath, O_CREAT | O_TRUNC, mbr, mbr_size);
/*
- * If we are installing the boot loader, read it from disk and copy the
- * slice table over from the existing MBR. If not, then point boot0
- * back at the MBR we just read in. After this, boot0 is the data to
- * write back to disk if we are going to do a write.
+ * If we are installing the boot loader, read it from disk and
+ * copy the slice table and NT Drive Serial Number over from the
+ * existing MBR. If not, then point boot0 back at the MBR we just
+ * read in. After this, boot0 is the data to write back to disk
+ * if we are going to do a write.
*/
if (B_flag) {
boot0_size = read_mbr(bpath, &boot0, 1);
memcpy(boot0 + OFF_PTBL, mbr + OFF_PTBL,
sizeof(struct dos_partition) * NDOSPART);
+ memcpy(boot0 + OFF_NTSERNUM, mbr + OFF_NTSERNUM, 4);
} else {
boot0 = mbr;
boot0_size = mbr_size;
@@ -374,6 +377,7 @@
static u_int8_t id0[] = {0xfc, 0x31, 0xc0, 0x8e, 0xc0, 0x8e, 0xd8,
0x8e, 0xd0, 0xbc, 0x00, 0x7c };
static u_int8_t id1[] = {'D', 'r', 'i', 'v', 'e', ' '};
+ static u_int8_t id1_alt[] = {'D', 'i', 's', 'k', ' '};
static struct {
unsigned off;
unsigned len;
@@ -381,11 +385,16 @@
} ident[2] = {
{0x0, sizeof(id0), id0},
{0x1b2, sizeof(id1), id1}
+ }, ident_alt[2] = {
+ {0x0, sizeof(id0), id0},
+ {0x1b2, sizeof(id1_alt), id1_alt}
};
+
unsigned int i;
for (i = 0; i < sizeof(ident) / sizeof(ident[0]); i++)
- if (memcmp(bs + ident[i].off, ident[i].key, ident[i].len))
+ if (memcmp(bs + ident[i].off, ident[i].key, ident[i].len) &&
+ memcmp(bs + ident_alt[i].off, ident_alt[i].key, ident_alt[i].len))
return 0;
return 1;
}
Index: sys/boot/i386/boot0/boot0.S
===================================================================
RCS file: /usr/CVS-Repository/src/sys/boot/i386/boot0/boot0.S,v
retrieving revision 1.16
diff -u -r1.16 boot0.S
--- sys/boot/i386/boot0/boot0.S 26 Mar 2007 21:56:13 -0000 1.16
+++ sys/boot/i386/boot0/boot0.S 25 Jul 2007 01:58:13 -0000
@@ -45,10 +45,10 @@
* Addresses in the sector of embedded data values.
* Accessed with negative offsets from the end of the relocated sector (%ebp).
*/
- .set _NXTDRV,-0x48 # Next drive
- .set _OPT,-0x47 # Default option
- .set _SETDRV,-0x46 # Drive to force
- .set _FLAGS,-0x45 # Flags
+ .set _NXTDRV,-0x49 # Next drive
+ .set _OPT,-0x53 # Default option
+ .set _SETDRV,-0x52 # Drive to force
+ .set _FLAGS,-0x51 # Flags
.set _TICKS,-0x44 # Timeout ticks
.set _FAKE,0x0 # Fake partition entry
.set _MNUOPT,0xc # Menu options
@@ -427,7 +427,7 @@
.byte os_dos-. # Windows
.byte os_dos-. # Windows
.byte os_linux-. # Linux
- .byte os_freebsd-. # FreeBSD
+ .byte os_bsd-. # FreeBSD
.byte os_bsd-. # OpenBSD
.byte os_bsd-. # NetBSD
.byte os_misc-. # Unknown
@@ -438,9 +438,13 @@
os_misc: .ascii "?"; .byte '?'|0x80
os_dos: .ascii "DO"; .byte 'S'|0x80
os_linux: .ascii "Linu"; .byte 'x'|0x80
-os_freebsd: .ascii "Free"
os_bsd: .ascii "BS"; .byte 'D'|0x80
+ .byte 0x90 # free space
+opt: .byte 0x0 # Option
+setdrv: .byte 0x80 # Drive to force
+flags: .byte FLAGS # Flags
+
.org PRT_OFF-0xe,0x90
.word B0MAGIC # Magic number
@@ -450,11 +454,9 @@
* Be especially careful that nxtdrv: must come after drive:, as it
* is part of the same string.
*/
-drive: .ascii "Drive "
+drive: .ascii "Disk "
nxtdrv: .byte 0x0 # Next drive number
-opt: .byte 0x0 # Option
-setdrv: .byte 0x80 # Drive to force
-flags: .byte FLAGS # Flags
+ .byte 0xa8,0xa8,0xa8,0xa8 # NT Drive Serial Number
ticks: .word TICKS # Delay
/*
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list