[Top][All Lists]

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

[PATCH] unique MBR signatures

From: Matt Domsch
Subject: [PATCH] unique MBR signatures
Date: Tue, 4 Jan 2005 17:23:21 -0600
User-agent: Mutt/1.4.1i

I've got Linux kernel code which tries to determine what the BIOS boot
disks are by storing the "mbr_signature" field (offset 440 in the MBR,
which is at the end of the boot_code section) for each of the
int13_dev8x devices, and presenting this to userspace through
/sys/firmware/edd/int13_dev8x/mbr_signature.  Then userspace can read
the MBR itself from /dev/{sda,hda,...}, compare the signatures, and
match disks.  This works if system-unique values are stored in each
disk's mbr_signature field in the MBR, and doesn't rely on BIOS EDD
3.0 to be available, or if available, correctly implemented. :-)

The code below writes a quasi-unique value (based on the usec value of
gettimeofday() into the mbr_signature field of the MBR if it is
otherwise zero.  On my x86 system, this contains three quasi-unique
bytes of data, the fourth (MSB) byte being zero always.

Doing this lets parted write these unique signatures to each disk at
mklabel time, or any time a disk has a zero in that field and is

The boot_code field is only 440 bytes long, per the Intel EFI
specification, with a 4-byte signature following, with two more bytes
of "unknown" use.  This only writes the 4-byte signature, without
touching the "unknown" field.

This has been in the Red Hat parted tree for a year, with no issues reported.


Matt Domsch
Software Architect
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

diff -urNp --exclude-from=3D/home/mdomsch/excludes --minimal parted-1.6.11.=
orig/libparted/disk_dos.c parted-1.6.11/libparted/disk_dos.c
--- parted-1.6.11.orig/libparted/disk_dos.c     Tue Mar  9 04:17:08 2004
+++ parted-1.6.11/libparted/disk_dos.c  Fri Jun 25 17:20:32 2004
@@ -19,6 +19,7 @@
 #include "config.h"
+#include <sys/time.h>
 #include <parted/parted.h>
 #include <parted/debug.h>
 #include <parted/endian.h>
@@ -107,7 +108,9 @@ struct _DosRawPartition {
 } __attribute__((packed));
 struct _DosRawTable {
-       char                    boot_code [446];
+       char                    boot_code [440];
+       uint32_t                mbr_signature;
+       uint16_t                Unknown;
        DosRawPartition         partitions [4];
        uint16_t                        magic;
 } __attribute__((packed));
@@ -769,6 +772,16 @@ write_extended_partitions (PedDisk* disk
                return write_empty_table (disk, ext_part->geom.start);
+static inline uint32_t set_mbr_signature(void)
+       struct timeval tv;
+       int rc;
+       rc = gettimeofday(&tv, NULL);
+       if (rc == -1)
+               return 0;
+       return (uint32_t)(tv.tv_usec & 0xFFFFFFFFUL);
 static int
 msdos_write (PedDisk* disk)
@@ -786,6 +799,9 @@ msdos_write (PedDisk* disk)
                memcpy (table.boot_code, MBR_BOOT_CODE,
                        sizeof (MBR_BOOT_CODE));
+       if (!table.mbr_signature)
+               table.mbr_signature = set_mbr_signature();
        memset (table.partitions, 0, sizeof (DosRawPartition) * 4);
        table.magic = PED_CPU_TO_LE16 (MSDOS_MAGIC);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]