]> git.hungrycats.org Git - linux/commitdiff
[PATCH] EDD: read disk80 MBR signature, export through edd module
authorAndrew Morton <akpm@osdl.org>
Wed, 4 Feb 2004 02:41:10 +0000 (18:41 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Wed, 4 Feb 2004 02:41:10 +0000 (18:41 -0800)
From: Matt Domsch <Matt_Domsch@dell.com>

There are 4 bytes in the MSDOS master boot record, at offset 0x1b8,
which may contain a per-system-unique signature.  By first writing a unique
signature to each disk in the system, then rebooting, and then reading the
MBR to get the signature for the boot disk (int13 dev 80h), userspace may
use it to compare against disks it knows as named /dev/[hs]d[a-z], and thus
determine which disk is the BIOS boot disk, thus where the /boot, / and
boot loaders should be placed.

This is useful in the case where the BIOS is not EDD3.0 compliant, thus
doesn't provide the PCI bus/dev/fn and IDE/SCSI location of the boot disk,
yet you need to know which disk is the boot disk.  It's most useful in OS
installers.

This patch retrieves the signature from the disk in setup.S, stores it in a
space reserved in the empty_zero_page, copies it somewhere safe in setup.c,
and exports it via /sys/firmware/edd/int13_disk80/mbr_signature in edd.c.
Code is covered under CONFIG_EDD=[ym].

Documentation/i386/zero-page.txt
arch/i386/boot/setup.S
arch/i386/kernel/edd.c
arch/i386/kernel/i386_ksyms.c
arch/i386/kernel/setup.c
include/asm-i386/edd.h
include/asm-i386/setup.h

index ba5caf7d76a134cd5a1f19e52ae374924bdadcfc..7cc2f05f86ac3438982e3940ca38ceb97892ed6a 100644 (file)
@@ -72,8 +72,10 @@ Offset       Type            Description
 0x21c  unsigned long   INITRD_SIZE, size in bytes of ramdisk image
 0x220  4 bytes         (setup.S)
 0x224  unsigned short  setup.S heap end pointer
+0x2cc  4 bytes         DISK80_SIG_BUFFER (setup.S)
 0x2d0 - 0x600          E820MAP
-0x600 - 0x7D4          EDDBUF (setup.S)
+0x600 - 0x7ff          EDDBUF (setup.S) for disk signature read sector
+0x600 - 0x7d3          EDDBUF (setup.S) for edd data
 
 0x800  string, 2K max  COMMAND_LINE, the kernel commandline as
                        copied using CL_OFFSET.
index e1977dea2fa52908ab821848fb8ff2120859780b..a4c3975ac412855fcaea611998623789f0d97513 100644 (file)
@@ -49,6 +49,8 @@
  * by Matt Domsch <Matt_Domsch@dell.com> October 2002
  * conformant to T13 Committee www.t13.org
  *   projects 1572D, 1484D, 1386D, 1226DT
+ * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
+ *     and Andrew Wilks <Andrew_Wilks@dell.com> September 2003
  */
 
 #include <linux/config.h>
@@ -578,6 +580,25 @@ done_apm_bios:
 #endif
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+# Read the first sector of device 80h and store the 4-byte signature
+       movl    $0xFFFFFFFF, %eax
+       movl    %eax, (DISK80_SIG_BUFFER)       # assume failure
+       movb    $READ_SECTORS, %ah
+       movb    $1, %al                         # read 1 sector
+       movb    $0x80, %dl                      # from device 80
+       movb    $0, %dh                         # at head 0
+       movw    $1, %cx                         # cylinder 0, sector 0
+       pushw   %es
+       pushw   %ds
+       popw    %es
+       movw    $EDDBUF, %bx
+       int     $0x13
+       jc      disk_sig_done
+       movl    (EDDBUF+MBR_SIG_OFFSET), %eax
+       movl    %eax, (DISK80_SIG_BUFFER)       # store success
+disk_sig_done:
+       popw    %es
+
 # Do the BIOS Enhanced Disk Drive calls
 # This consists of two calls:
 #    int 13h ah=41h "Check Extensions Present"
index 384eeb598355a8670a63d26b14a6f0b41202b58f..416d47d5a2f992b59281bda80e9a8e10857904b4 100644 (file)
@@ -2,6 +2,7 @@
  * linux/arch/i386/kernel/edd.c
  *  Copyright (C) 2002, 2003 Dell Inc.
  *  by Matt Domsch <Matt_Domsch@dell.com>
+ *  disk80 signature by Matt Domsch, Andrew Wilks, and Sandeep K. Shandilya
  *
  * BIOS Enhanced Disk Drive Services (EDD)
  * conformant to T13 Committee www.t13.org
@@ -59,9 +60,9 @@ MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
 MODULE_DESCRIPTION("sysfs interface to BIOS EDD information");
 MODULE_LICENSE("GPL");
 
-#define EDD_VERSION "0.10 2003-Oct-11"
+#define EDD_VERSION "0.12 2004-Jan-26"
 #define EDD_DEVICE_NAME_SIZE 16
-#define REPORT_URL "http://domsch.com/linux/edd30/results.html"
+#define REPORT_URL "http://linux.dell.com/edd/results.html"
 
 #define left (PAGE_SIZE - (p - buf) - 1)
 
@@ -259,6 +260,14 @@ edd_show_version(struct edd_device *edev, char *buf)
        return (p - buf);
 }
 
+static ssize_t
+edd_show_disk80_sig(struct edd_device *edev, char *buf)
+{
+       char *p = buf;
+       p += snprintf(p, left, "0x%08x\n", edd_disk80_sig);
+       return (p - buf);
+}
+
 static ssize_t
 edd_show_extensions(struct edd_device *edev, char *buf)
 {
@@ -429,6 +438,15 @@ edd_has_edd30(struct edd_device *edev)
        return 1;
 }
 
+static int
+edd_has_disk80_sig(struct edd_device *edev)
+{
+       struct edd_info *info = edd_dev_get_info(edev);
+       if (!edev || !info)
+               return 0;
+       return info->device == 0x80;
+}
+
 static EDD_DEVICE_ATTR(raw_data, 0444, edd_show_raw_data, NULL);
 static EDD_DEVICE_ATTR(version, 0444, edd_show_version, NULL);
 static EDD_DEVICE_ATTR(extensions, 0444, edd_show_extensions, NULL);
@@ -443,6 +461,7 @@ static EDD_DEVICE_ATTR(default_sectors_per_track, 0444,
                       edd_has_default_sectors_per_track);
 static EDD_DEVICE_ATTR(interface, 0444, edd_show_interface, edd_has_edd30);
 static EDD_DEVICE_ATTR(host_bus, 0444, edd_show_host_bus, edd_has_edd30);
+static EDD_DEVICE_ATTR(mbr_signature, 0444, edd_show_disk80_sig, edd_has_disk80_sig);
 
 
 /* These are default attributes that are added for every edd
@@ -464,6 +483,7 @@ static struct edd_attribute * edd_attrs[] = {
        &edd_attr_default_sectors_per_track,
        &edd_attr_interface,
        &edd_attr_host_bus,
+       &edd_attr_mbr_signature,
        NULL,
 };
 
index 09e87744c79ef10248bab435106e349277dc13fe..ae3617dfa6191d0add52d2093df737fcbef76593 100644 (file)
@@ -32,7 +32,6 @@
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/nmi.h>
-#include <asm/edd.h>
 #include <asm/ist.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
@@ -203,11 +202,6 @@ EXPORT_SYMBOL(kunmap_atomic);
 EXPORT_SYMBOL(kmap_atomic_to_page);
 #endif
 
-#ifdef CONFIG_EDD_MODULE
-EXPORT_SYMBOL(edd);
-EXPORT_SYMBOL(eddnr);
-#endif
-
 #if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
 EXPORT_SYMBOL(ist_info);
 #endif
index ac11f7c9e5d050702ac73563405982791fc49fab..c04f2296f76f964fc9ca729c2e67454f1c62d37a 100644 (file)
@@ -444,6 +444,12 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 unsigned char eddnr;
 struct edd_info edd[EDDMAXNR];
+unsigned int edd_disk80_sig;
+#ifdef CONFIG_EDD_MODULE
+EXPORT_SYMBOL(eddnr);
+EXPORT_SYMBOL(edd);
+EXPORT_SYMBOL(edd_disk80_sig);
+#endif
 /**
  * copy_edd() - Copy the BIOS EDD information
  *              from empty_zero_page into a safe place.
@@ -453,6 +459,7 @@ static inline void copy_edd(void)
 {
      eddnr = EDD_NR;
      memcpy(edd, EDD_BUF, sizeof(edd));
+     edd_disk80_sig = DISK80_SIGNATURE;
 }
 #else
 #define copy_edd() do {} while (0)
index 3bae533f3d2f7d4564dd7300571e15b6de7a8457..6f7dbc6db81125d518b4738fdc636ba67209b552 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * linux/include/asm-i386/edd.h
- *  Copyright (C) 2002 Dell Inc.
+ *  Copyright (C) 2002, 2003 Dell Inc.
  *  by Matt Domsch <Matt_Domsch@dell.com>
  *
  * structures and definitions for the int 13h, ax={41,48}h
@@ -41,6 +41,9 @@
 #define EDDMAGIC1 0x55AA
 #define EDDMAGIC2 0xAA55
 
+#define READ_SECTORS 0x02
+#define MBR_SIG_OFFSET 0x1B8
+#define DISK80_SIG_BUFFER 0x2cc
 #ifndef __ASSEMBLY__
 
 #define EDD_EXT_FIXED_DISK_ACCESS           (1 << 0)
@@ -167,6 +170,7 @@ struct edd_info {
 
 extern struct edd_info edd[EDDMAXNR];
 extern unsigned char eddnr;
+extern unsigned int edd_disk80_sig;
 #endif                         /*!__ASSEMBLY__ */
 
 #endif                         /* _ASM_I386_EDD_H */
index bead49efcf04d1e55cba62bfe8265867f5946407..bac2c9f0f7d88171c1068313cf27382e4ef122b7 100644 (file)
@@ -44,6 +44,7 @@
 #define INITRD_START (*(unsigned long *) (PARAM+0x218))
 #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
 #define EDID_INFO   (*(struct edid_info *) (PARAM+0x440))
+#define DISK80_SIGNATURE (*(unsigned int*) (PARAM+DISK80_SIG_BUFFER))
 #define EDD_NR     (*(unsigned char *) (PARAM+EDDNR))
 #define EDD_BUF     ((struct edd_info *) (PARAM+EDDBUF))
 #define COMMAND_LINE ((char *) (PARAM+2048))