]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2009-06-11 Vladimir Serbinenko <phcoder@gmail.com>
authorphcoder <phcoder@localhost>
Thu, 11 Jun 2009 16:13:39 +0000 (16:13 +0000)
committerphcoder <phcoder@localhost>
Thu, 11 Jun 2009 16:13:39 +0000 (16:13 +0000)
Drivemap fixes

* commands/i386/pc/drivemap.c (grub_get_root_biosnumber_drivemap):
new function
(grub_get_root_biosnumber_saved): new variable
(GRUB_MOD_INIT): register grub_get_root_biosnumber_drivemap
(GRUB_MOD_FINI): unregister grub_get_root_biosnumber_drivemap
* commands/i386/pc/drivemap_int13h.S (grub_drivemap_handler): restore
%dx after the call if necessary
* conf/common.rmk (pkglib_MODULES): remove boot.mod
(boot_mod_SOURCES): remove
(boot_mod_CFLAGS): remove
(boot_mod_LDFLAGS): remove
* conf/i386-coreboot.rmk (pkglib_MODULES): add boot.mod
(boot_mod_SOURCES): new variable
(boot_mod_CFLAGS): likewise
(boot_mod_LDFLAGS): likewise
* conf/i386-efi.rmk: likewise
* conf/i386-ieee1275.rmk: likewise
* conf/i386-pc.rmk: likewise
* conf/powerpc-ieee1275.rmk: likewise
* conf/sparc64-ieee1275.rmk: likewise
* conf/x86_64-efi.rmk: likewise
* include/grub/i386/pc/biosnum.h: new file
* lib/i386/pc/biosnum.c: likewise
* loader/i386/bsd.c (grub_bsd_get_device): use grub_get_root_biosnumber
* loader/i386/multiboot.c (grub_multiboot_get_bootdev): likewise
* loader/i386/pc/chainloader.c (grub_chainloader_cmd): likewise

16 files changed:
ChangeLog
commands/i386/pc/drivemap.c
commands/i386/pc/drivemap_int13h.S
conf/common.rmk
conf/i386-coreboot.rmk
conf/i386-efi.rmk
conf/i386-ieee1275.rmk
conf/i386-pc.rmk
conf/powerpc-ieee1275.rmk
conf/sparc64-ieee1275.rmk
conf/x86_64-efi.rmk
include/grub/i386/pc/biosnum.h [new file with mode: 0644]
lib/i386/pc/biosnum.c [new file with mode: 0644]
loader/i386/bsd.c
loader/i386/multiboot.c
loader/i386/pc/chainloader.c

index 9802e0e397fd504ab86b30f0332d652362517972..f93ec8ca54398bcafaf9d0452c17115356928f80 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2009-06-11  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Drivemap fixes
+
+       * commands/i386/pc/drivemap.c (grub_get_root_biosnumber_drivemap):
+       new function
+       (grub_get_root_biosnumber_saved): new variable
+       (GRUB_MOD_INIT): register grub_get_root_biosnumber_drivemap
+       (GRUB_MOD_FINI): unregister grub_get_root_biosnumber_drivemap
+       * commands/i386/pc/drivemap_int13h.S (grub_drivemap_handler): restore 
+       %dx after the call if necessary
+       * conf/common.rmk (pkglib_MODULES): remove boot.mod
+       (boot_mod_SOURCES): remove
+       (boot_mod_CFLAGS): remove
+       (boot_mod_LDFLAGS): remove
+       * conf/i386-coreboot.rmk (pkglib_MODULES): add boot.mod
+       (boot_mod_SOURCES): new variable
+       (boot_mod_CFLAGS): likewise
+       (boot_mod_LDFLAGS): likewise
+       * conf/i386-efi.rmk: likewise
+       * conf/i386-ieee1275.rmk: likewise
+       * conf/i386-pc.rmk: likewise
+       * conf/powerpc-ieee1275.rmk: likewise
+       * conf/sparc64-ieee1275.rmk: likewise
+       * conf/x86_64-efi.rmk: likewise
+       * include/grub/i386/pc/biosnum.h: new file
+       * lib/i386/pc/biosnum.c: likewise
+       * loader/i386/bsd.c (grub_bsd_get_device): use grub_get_root_biosnumber
+       * loader/i386/multiboot.c (grub_multiboot_get_bootdev): likewise
+       * loader/i386/pc/chainloader.c (grub_chainloader_cmd): likewise
+       
 2009-06-10  Pavel Roskin  <proski@gnu.org>
 
        * io/gzio.c (test_header): Don't reuse one buffer for all data.
index aeb354f1b402b2aa5ffa21bcdf9477aebf16567f..52424c3d1a78c534b5bf15dc8eb74835b3124481 100644 (file)
@@ -23,8 +23,9 @@
 #include <grub/misc.h>
 #include <grub/disk.h>
 #include <grub/loader.h>
+#include <grub/env.h>
 #include <grub/machine/memory.h>
-
+#include <grub/machine/biosnum.h>
 
 
 /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
@@ -356,10 +357,49 @@ uninstall_int13_handler (void)
   return GRUB_ERR_NONE;
 }
 
+static int
+grub_get_root_biosnumber_drivemap (void)
+{
+  char *biosnum;
+  int ret = -1;
+  grub_device_t dev;
+
+  biosnum = grub_env_get ("biosnum");
+
+  if (biosnum)
+    return grub_strtoul (biosnum, 0, 0);
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->dev 
+      && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
+    {
+      drivemap_node_t *curnode = map_head;
+      ret = (int) dev->disk->id;
+      while (curnode)
+       {
+         if (curnode->redirto == ret)
+           {
+             ret = curnode->newdrive;
+             break;
+           }
+         curnode = curnode->next;
+       }
+
+    }
+
+  if (dev)
+    grub_device_close (dev);
+
+  return ret;
+}
+
 static grub_extcmd_t cmd;
+static int (*grub_get_root_biosnumber_saved) (void);
 
 GRUB_MOD_INIT (drivemap)
 {
+  grub_get_root_biosnumber_saved = grub_get_root_biosnumber;
+  grub_get_root_biosnumber = grub_get_root_biosnumber_drivemap;
   cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap,
                                        GRUB_COMMAND_FLAG_BOTH,
                                        "drivemap"
@@ -374,6 +414,7 @@ GRUB_MOD_INIT (drivemap)
 
 GRUB_MOD_FINI (drivemap)
 {
+  grub_get_root_biosnumber = grub_get_root_biosnumber_saved;
   grub_loader_unregister_preboot_hook (drivemap_hook);
   drivemap_hook = 0;
   grub_unregister_extcmd (cmd);
index 7a3e8e73f1d3ee7f8b5e6ce9cfde854be9b16317..96848fb65d7c4af4f10f7a8f243dd909ab723a09 100644 (file)
 
 /* The replacement int13 handler.   Preserve all registers.  */
 FUNCTION(grub_drivemap_handler)
+       /* Save %dx for future restore. */
+       push    %dx
+       /* Push flags. Used to simulate interrupt with original flags. */
+       pushf
+
        /* Map the drive number (always in DL).  */
        push    %ax
        push    %bx
@@ -51,11 +56,48 @@ not_found:
        pop     %bx
        pop     %ax
 
-       /* Upon arrival to this point the stack must be exactly like at entry.
-          This long jump will transfer the caller's stack to the old INT13
-          handler, thus making it return directly to the original caller.  */
-       .byte   0xea
+       cmpb    $0x8, %ah
+       jz      norestore
+       cmpb    $0x15, %ah
+       jz      norestore
+
+       /* Restore flags.  */
+       popf
+       pushf
+
+       lcall *%cs:INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler))
+       
+       push    %bp
+       mov     %sp, %bp
+
+tail:
+       
+       pushf
+       pop     %dx
+       mov     %dx, 8(%bp)
+
+       pop     %bp
+       
+       /* Restore %dx.  */
+       pop     %dx
+       iret
+
+norestore:
+
+       /* Restore flags.  */
+       popf
+       pushf
+
+       lcall *%cs:INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler))
+
+       push    %bp
+       mov     %sp, %bp
+       
+       /* Save %dx.  */
+       mov     %dx, 2(%bp)
 
+       jmp tail
+       
 /* Far pointer to the old handler.  Stored as a CS:IP in the style of real-mode
    IVT entries (thus PI:SC in mem).  */
 VARIABLE(grub_drivemap_oldhandler)
index 027eff2f843c033a957163de369749d46642a8c1..2dcf2d628cd854f4747f605def72332cfab989a5 100644 (file)
@@ -353,7 +353,7 @@ pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod      \
        loopback.mod fs_uuid.mod configfile.mod echo.mod        \
        terminfo.mod test.mod blocklist.mod hexdump.mod         \
        read.mod sleep.mod loadenv.mod crc.mod parttool.mod     \
-       pcpart.mod memrw.mod boot.mod normal.mod sh.mod lua.mod \
+       pcpart.mod memrw.mod normal.mod sh.mod lua.mod  \
        gptsync.mod true.mod
 
 # For gptsync.mod.
@@ -361,11 +361,6 @@ gptsync_mod_SOURCES = commands/gptsync.c
 gptsync_mod_CFLAGS = $(COMMON_CFLAGS)
 gptsync_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-# For boot.mod.
-boot_mod_SOURCES = commands/boot.c
-boot_mod_CFLAGS = $(COMMON_CFLAGS)
-boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For minicmd.mod.
 minicmd_mod_SOURCES = commands/minicmd.c
 minicmd_mod_CFLAGS = $(COMMON_CFLAGS)
index 2f768c0fd3a9a5902076e2abf19ddded2bf73383..483f279ad7bc08af5d47840f73e7c578bbe1f858 100644 (file)
@@ -109,6 +109,12 @@ pkglib_MODULES = linux.mod multiboot.mod           \
        halt.mod datetime.mod date.mod datehook.mod     \
        lsmmap.mod mmap.mod
 
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For mmap.mod.
 mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
 mmap_mod_CFLAGS = $(COMMON_CFLAGS)
index 91e271d8cfbc911fa966188eb7fa99fa31d99ff0..d1467338278770011c16d87218d9a6d8d3d80f38 100644 (file)
@@ -117,6 +117,12 @@ symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.
 kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh
        /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
 
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For acpi.mod.
 acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
 acpi_mod_CFLAGS = $(COMMON_CFLAGS)
index 961e61617323b5e7db1a07df16caa78747c80db6..6e91b420c7cff05c27ad7baa461b23fd1ff867d2 100644 (file)
@@ -108,6 +108,12 @@ pkglib_MODULES = halt.mod reboot.mod suspend.mod           \
        nand.mod memdisk.mod pci.mod lspci.mod datetime.mod     \
        date.mod datehook.mod lsmmap.mod mmap.mod
 
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For mmap.mod.
 mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
 mmap_mod_CFLAGS = $(COMMON_CFLAGS)
index 4a94443b694564f7df0a7d754d8a860ae0938a86..abb6fd5651dd3310e54bdf105998505b64faa780 100644 (file)
@@ -189,6 +189,12 @@ pkglib_MODULES = biosdisk.mod chain.mod \
        usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
        efiemu.mod mmap.mod acpi.mod drivemap.mod
 
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For drivemap.mod.
 drivemap_mod_SOURCES = commands/i386/pc/drivemap.c \
                        commands/i386/pc/drivemap_int13h.S
index 6411111b4e29d78ae8b674c4872864648008739e..157b6e2c35419f2ea3e8f2d1e2eb64d67e5cd712 100644 (file)
@@ -119,6 +119,12 @@ pkglib_MODULES = halt.mod \
        memdisk.mod \
        lsmmap.mod
 
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For linux.mod.
 linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
 linux_mod_CFLAGS = $(COMMON_CFLAGS)
index d061416a21663ec86e1cd18f6b1c352172de807c..3a8cbe2607042e45d27819bf6fea60c1b977da90 100644 (file)
@@ -149,6 +149,12 @@ pkglib_MODULES = halt.mod \
        memdisk.mod \
        lsmmap.mod
 
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For linux.mod.
 linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c
 linux_mod_CFLAGS = $(COMMON_CFLAGS)
index 175f8cca492d934cac528e6f0587a2bf127beed6..82d000506ff4e8f73513ece86a9322734742e103 100644 (file)
@@ -115,6 +115,12 @@ symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.
 kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh
        /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
 
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For acpi.mod.
 acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
 acpi_mod_CFLAGS = $(COMMON_CFLAGS)
diff --git a/include/grub/i386/pc/biosnum.h b/include/grub/i386/pc/biosnum.h
new file mode 100644 (file)
index 0000000..29c8ecc
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef GRUB_BIOSNUM_MACHINE_HEADER
+#define GRUB_BIOSNUM_MACHINE_HEADER    1
+
+extern int (*grub_get_root_biosnumber) (void);
+
+#endif
diff --git a/lib/i386/pc/biosnum.c b/lib/i386/pc/biosnum.c
new file mode 100644 (file)
index 0000000..1f9b5f3
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+
+static int
+grub_get_root_biosnumber_default (void)
+{
+  char *biosnum;
+  int ret = -1;
+  grub_device_t dev;
+
+  biosnum = grub_env_get ("biosnum");
+
+  if (biosnum)
+    return grub_strtoul (biosnum, 0, 0);
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->dev 
+      && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
+    ret = (int) dev->disk->id;
+
+  if (dev)
+    grub_device_close (dev);
+
+  return ret;
+}
+
+int (*grub_get_root_biosnumber) (void) = grub_get_root_biosnumber_default;
index 81d45a0eb2f2b60fe91ff2fb5c9434d7a2ea828b..c6a97724df13f3b7301a3656c56b9181524b31dd 100644 (file)
 #include <grub/gzio.h>
 #include <grub/aout.h>
 #include <grub/command.h>
+#ifdef GRUB_MACHINE_PCBIOS
+#include <grub/machine/biosnum.h>
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/partition.h>
+#endif
 
 #define ALIGN_DWORD(a) ALIGN_UP (a, 4)
 #define ALIGN_QWORD(a) ALIGN_UP (a, 8)
@@ -81,23 +87,22 @@ grub_bsd_get_device (grub_uint32_t * biosdev,
                     grub_uint32_t * slice, grub_uint32_t * part)
 {
   char *p;
-
-  *biosdev = *unit = *slice = *part = 0;
-  p = grub_env_get ("root");
-  if ((p) && ((p[0] == 'h') || (p[0] == 'f')) && (p[1] == 'd') &&
-      (p[2] >= '0') && (p[2] <= '9'))
+  grub_device_t dev; 
+
+  *biosdev = grub_get_root_biosnumber () & 0xff;
+  *unit = (*biosdev & 0x7f);
+  *slice = 0xff;
+  *part = 0xff;
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
     {
-      if (p[0] == 'h')
-       *biosdev = 0x80;
-
-      *unit = grub_strtoul (p + 2, &p, 0);
-      *biosdev += *unit;
 
-      if ((p) && (p[0] == ','))
+      p = dev->disk->partition->partmap->get_name (dev->disk->partition);
+      if (p)
        {
-         if ((p[1] >= '0') && (p[1] <= '9'))
+         if ((p[0] >= '0') && (p[0] <= '9'))
            {
-             *slice = grub_strtoul (p + 1, &p, 0);
+             *slice = grub_strtoul (p, &p, 0);
 
              if ((p) && (p[0] == ','))
                p++;
@@ -107,6 +112,8 @@ grub_bsd_get_device (grub_uint32_t * biosdev,
            *part = p[0] - 'a';
        }
     }
+  if (dev)
+    grub_device_close (dev);
 }
 
 static grub_err_t
index cc45a4e9718cdeb3f7c3b8cd0732a93943984888..efca6511cbfa8de181451832320c9ba06fcbcb84 100644 (file)
 #include <grub/misc.h>
 #include <grub/gzio.h>
 #include <grub/env.h>
+#ifdef GRUB_MACHINE_PCBIOS
+#include <grub/machine/biosnum.h>
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/partition.h>
+#endif
 
 extern grub_dl_t my_mod;
 static struct grub_multiboot_info *mbi, *mbi_dest;
@@ -148,46 +154,42 @@ grub_multiboot_load_elf (grub_file_t file, void *buffer)
 static int
 grub_multiboot_get_bootdev (grub_uint32_t *bootdev)
 {
+#ifdef GRUB_MACHINE_PCBIOS
   char *p;
+  grub_uint32_t biosdev, slice = ~0, part = ~0;
+  grub_device_t dev;
 
-  p = grub_env_get ("root");
-  if ((p) && ((p[0] == 'h') || (p[0] == 'f')) && (p[1] == 'd') &&
-      (p[2] >= '0') && (p[2] <= '9'))
-    {
-      grub_uint32_t bd;
+  biosdev = grub_get_root_biosnumber ();
 
-      bd = (p[0] == 'h') ? 0x80 : 0;
-      bd += grub_strtoul (p + 2, &p, 0);
-      bd <<= 24;
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
+    {
 
-      if ((p) && (p[0] == ','))
+      p = dev->disk->partition->partmap->get_name (dev->disk->partition);
+      if (p)
        {
-         if ((p[1] >= '0') && (p[1] <= '9'))
+         if ((p[0] >= '0') && (p[0] <= '9'))
            {
-
-             bd += ((grub_strtoul (p + 1, &p, 0) - 1) & 0xFF) << 16;
+             slice = grub_strtoul (p, &p, 0);
 
              if ((p) && (p[0] == ','))
                p++;
            }
-          else
-            bd += 0xFF0000;
 
          if ((p[0] >= 'a') && (p[0] <= 'z'))
-            bd += (p[0] - 'a') << 8;
-          else
-            bd += 0xFF00;
+           part = p[0] - 'a';
        }
-      else
-        bd += 0xFFFF00;
-
-      bd += 0xFF;
-
-      *bootdev = bd;
-      return 1;
     }
-
+  if (dev)
+    grub_device_close (dev);
+
+  *bootdev = ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16) 
+    | ((part & 0xff) << 16) | 0xff;
+  return (biosdev != ~0UL);
+#else
+  *bootdev = 0xffffffff;
   return 0;
+#endif
 }
 
 void
index 3befd5e59fb9d98b0b16c30e22233bbe9470eeb0..caf1450e4d1bbf92054af52dea6b680e61149203 100644 (file)
@@ -31,6 +31,7 @@
 #include <grub/machine/memory.h>
 #include <grub/dl.h>
 #include <grub/command.h>
+#include <grub/machine/biosnum.h>
 
 static grub_dl_t my_mod;
 static int boot_drive;
@@ -89,30 +90,19 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
   grub_file_close (file);
 
   /* Obtain the partition table from the root device.  */
+  drive = grub_get_root_biosnumber ();
   dev = grub_device_open (0);
-  if (dev)
+  if (dev && dev->disk && dev->disk->partition)
     {
-      grub_disk_t disk = dev->disk;
-
-      if (disk)
-       {
-         grub_partition_t p = disk->partition;
-
-         /* In i386-pc, the id is equal to the BIOS drive number.  */
-         drive = (int) disk->id;
-
-         if (p)
-           {
-             grub_disk_read (disk, p->offset, 446, 64,
-                             (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
-             part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
-                                   + (p->index << 4));
-           }
-       }
-
-      grub_device_close (dev);
+      grub_disk_read (dev->disk, dev->disk->partition->offset, 446, 64,
+                     (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
+      part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
+                           + (dev->disk->partition->index << 4));
     }
 
+  if (dev)
+    grub_device_close (dev);
+  
   /* Ignore errors. Perhaps it's not fatal.  */
   grub_errno = GRUB_ERR_NONE;