[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
written.
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.
Thanks,
Matt
--
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);
- [PATCH] unique MBR signatures,
Matt Domsch <=