[2298] 2009-06-11 Vladimir Serbinenko <[email protected]>

Vladimir Serbinenko <[email protected]>
Newsgroups gmane.comp.boot-loaders.grub.cvs
Message-ID <[email protected]>
Revision: 2298
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2298
Author:   phcoder
Date:     2009-06-11 16:13:39 +0000 (Thu, 11 Jun 2009)
Log Message:
-----------
2009-06-11  Vladimir Serbinenko  <[email protected]>

	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
	

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/commands/i386/pc/drivemap.c
    trunk/grub2/commands/i386/pc/drivemap_int13h.S
    trunk/grub2/conf/common.rmk
    trunk/grub2/conf/i386-coreboot.rmk
    trunk/grub2/conf/i386-efi.rmk
    trunk/grub2/conf/i386-ieee1275.rmk
    trunk/grub2/conf/i386-pc.rmk
    trunk/grub2/conf/powerpc-ieee1275.rmk
    trunk/grub2/conf/sparc64-ieee1275.rmk
    trunk/grub2/conf/x86_64-efi.rmk
    trunk/grub2/loader/i386/bsd.c
    trunk/grub2/loader/i386/multiboot.c
    trunk/grub2/loader/i386/pc/chainloader.c

Added Paths:
-----------
    trunk/grub2/include/grub/i386/pc/biosnum.h
    trunk/grub2/lib/i386/pc/
    trunk/grub2/lib/i386/pc/biosnum.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/ChangeLog	2009-06-11 16:13:39 UTC (rev 2298)
@@ -1,3 +1,34 @@
+2009-06-11  Vladimir Serbinenko  <[email protected]>
+
+	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  <[email protected]>
 
 	* io/gzio.c (test_header): Don't reuse one buffer for all data.

Modified: trunk/grub2/commands/i386/pc/drivemap.c
===================================================================
--- trunk/grub2/commands/i386/pc/drivemap.c	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/commands/i386/pc/drivemap.c	2009-06-11 16:13:39 UTC (rev 2298)
@@ -23,10 +23,11 @@
 #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.  */
 static grub_uint32_t *const int13slot = UINT_TO_PTR (4 * 0x13);
 
@@ -356,10 +357,49 @@
   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_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);

Modified: trunk/grub2/commands/i386/pc/drivemap_int13h.S
===================================================================
--- trunk/grub2/commands/i386/pc/drivemap_int13h.S	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/commands/i386/pc/drivemap_int13h.S	2009-06-11 16:13:39 UTC (rev 2298)
@@ -27,6 +27,11 @@
 
 /* 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 @@
 	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)

Modified: trunk/grub2/conf/common.rmk
===================================================================
--- trunk/grub2/conf/common.rmk	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/conf/common.rmk	2009-06-11 16:13:39 UTC (rev 2298)
@@ -353,7 +353,7 @@
 	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_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)

Modified: trunk/grub2/conf/i386-coreboot.rmk
===================================================================
--- trunk/grub2/conf/i386-coreboot.rmk	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/conf/i386-coreboot.rmk	2009-06-11 16:13:39 UTC (rev 2298)
@@ -109,6 +109,12 @@
 	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)

Modified: trunk/grub2/conf/i386-efi.rmk
===================================================================
--- trunk/grub2/conf/i386-efi.rmk	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/conf/i386-efi.rmk	2009-06-11 16:13:39 UTC (rev 2298)
@@ -117,6 +117,12 @@
 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)

Modified: trunk/grub2/conf/i386-ieee1275.rmk
===================================================================
--- trunk/grub2/conf/i386-ieee1275.rmk	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/conf/i386-ieee1275.rmk	2009-06-11 16:13:39 UTC (rev 2298)
@@ -108,6 +108,12 @@
 	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)

Modified: trunk/grub2/conf/i386-pc.rmk
===================================================================
--- trunk/grub2/conf/i386-pc.rmk	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/conf/i386-pc.rmk	2009-06-11 16:13:39 UTC (rev 2298)
@@ -189,6 +189,12 @@
 	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

Modified: trunk/grub2/conf/powerpc-ieee1275.rmk
===================================================================
--- trunk/grub2/conf/powerpc-ieee1275.rmk	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/conf/powerpc-ieee1275.rmk	2009-06-11 16:13:39 UTC (rev 2298)
@@ -119,6 +119,12 @@
 	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)

Modified: trunk/grub2/conf/sparc64-ieee1275.rmk
===================================================================
--- trunk/grub2/conf/sparc64-ieee1275.rmk	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/conf/sparc64-ieee1275.rmk	2009-06-11 16:13:39 UTC (rev 2298)
@@ -149,6 +149,12 @@
 	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)

Modified: trunk/grub2/conf/x86_64-efi.rmk
===================================================================
--- trunk/grub2/conf/x86_64-efi.rmk	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/conf/x86_64-efi.rmk	2009-06-11 16:13:39 UTC (rev 2298)
@@ -115,6 +115,12 @@
 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)

Added: trunk/grub2/include/grub/i386/pc/biosnum.h
===================================================================
--- trunk/grub2/include/grub/i386/pc/biosnum.h	                        (rev 0)
+++ trunk/grub2/include/grub/i386/pc/biosnum.h	2009-06-11 16:13:39 UTC (rev 2298)
@@ -0,0 +1,6 @@
+#ifndef GRUB_BIOSNUM_MACHINE_HEADER
+#define GRUB_BIOSNUM_MACHINE_HEADER	1
+
+extern int (*grub_get_root_biosnumber) (void);
+
+#endif

Added: trunk/grub2/lib/i386/pc/biosnum.c
===================================================================
--- trunk/grub2/lib/i386/pc/biosnum.c	                        (rev 0)
+++ trunk/grub2/lib/i386/pc/biosnum.c	2009-06-11 16:13:39 UTC (rev 2298)
@@ -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;

Modified: trunk/grub2/loader/i386/bsd.c
===================================================================
--- trunk/grub2/loader/i386/bsd.c	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/loader/i386/bsd.c	2009-06-11 16:13:39 UTC (rev 2298)
@@ -33,6 +33,12 @@
 #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_uint32_t * slice, grub_uint32_t * part)
 {
   char *p;
+  grub_device_t dev; 
 
-  *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'))
+  *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 @@
 	    *part = p[0] - 'a';
 	}
     }
+  if (dev)
+    grub_device_close (dev);
 }
 
 static grub_err_t

Modified: trunk/grub2/loader/i386/multiboot.c
===================================================================
--- trunk/grub2/loader/i386/multiboot.c	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/loader/i386/multiboot.c	2009-06-11 16:13:39 UTC (rev 2298)
@@ -42,6 +42,12 @@
 #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 @@
 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'))
+  biosdev = grub_get_root_biosnumber ();
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
     {
-      grub_uint32_t bd;
 
-      bd = (p[0] == 'h') ? 0x80 : 0;
-      bd += grub_strtoul (p + 2, &p, 0);
-      bd <<= 24;
-
-      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, &p, 0);
 
-	      bd += ((grub_strtoul (p + 1, &p, 0) - 1) & 0xFF) << 16;
-
 	      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

Modified: trunk/grub2/loader/i386/pc/chainloader.c
===================================================================
--- trunk/grub2/loader/i386/pc/chainloader.c	2009-06-11 01:06:39 UTC (rev 2297)
+++ trunk/grub2/loader/i386/pc/chainloader.c	2009-06-11 16:13:39 UTC (rev 2298)
@@ -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_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;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.