Re: [PATCH] drivemap fixes

2009-06-11 Thread Pavel Roskin

Quoting Vladimir 'phcoder' Serbinenko phco...@gmail.com:


On Mon, Jun 8, 2009 at 4:10 AM, Pavel Roskinpro...@gnu.org wrote:

 Also, it would be great
if you specify, which exactly problems the patch fixes.

You missed that part because it was in the previous drivemap thread.


It would be helpful if you summarize the changes in the patch  
description.  That would make it easier to review the patch for those  
who don't have time to go through the list archives.



It fixes 2 problems: grub2 passes incorrect boot number and %dl not
being restored after int 0x13


As for the later, it should be documented in comments in  
drivemap_int13h.S.  The code is very unclear with regard to what  
exactly is being restored.


Also, I'll appreciate if you avoid adding trailing whitespace in your  
patches.  The changes to drivemap_int13h.S also introduce pointless  
spaces before some tabs.


--
Regards,
Pavel Roskin


___
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] drivemap fixes

2009-06-08 Thread Vladimir 'phcoder' Serbinenko
On Mon, Jun 8, 2009 at 4:10 AM, Pavel Roskinpro...@gnu.org wrote:
  Also, it would be great
 if you specify, which exactly problems the patch fixes.
You missed that part because it was in the previous drivemap thread.
It fixes 2 problems: grub2 passes incorrect boot number and %dl not
being restored after int 0x13

 As for the fixes to the handler, I think they should be submitted
 separately.
They were together because there have already been discussion about
previous version of %dl fix

 --
 Regards,
 Pavel Roskin


 ___
 Grub-devel mailing list
 Grub-devel@gnu.org
 http://lists.gnu.org/mailman/listinfo/grub-devel




-- 
Regards
Vladimir 'phcoder' Serbinenko
diff --git a/ChangeLog b/ChangeLog
index cb6fe3f..ff534ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2009-06-08  Vladimir Serbinenko  phco...@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-08  Felix Zielcke  fziel...@z-51.de
 
 	* commands/true.c: New file.  Implement the true and false commands.
diff --git a/commands/i386/pc/drivemap.c b/commands/i386/pc/drivemap.c
index 898fb51..92781a0 100644
--- a/commands/i386/pc/drivemap.c
+++ b/commands/i386/pc/drivemap.c
@@ -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);
diff --git a/commands/i386/pc/drivemap_int13h.S b/commands/i386/pc/drivemap_int13h.S
index 7a3e8e7..96848fb 100644
--- a/commands/i386/pc/drivemap_int13h.S
+++ b/commands/i386/pc/drivemap_int13h.S
@@ -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 @@ 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
+	
+	/* 

Re: [PATCH] drivemap fixes

2009-06-07 Thread Pavel Roskin
On Fri, 2009-06-05 at 16:27 +0200, Vladimir 'phcoder' Serbinenko wrote:
 Hello. As suggested by Javier Martín I move this to a new thread. This
 patch fixes some problems with determining bios number of a disk.
 biosnum is in boot.mod because it's where it will cause the least of
 possible core.img increase (3 of 5 loaders on pc need biosnum).
 Thisforced to move boot.mod to platform-specific files but this
 inflexibility of build system is a subject for another patch

I'll appreciate if you also provide ChangeLog.  Also, it would be great
if you specify, which exactly problems the patch fixes.

As for the fixes to the handler, I think they should be submitted
separately.  Please avoid non-words like postamble.  Comments would be
nice.  I would try to avoid having two long calls if possible.

-- 
Regards,
Pavel Roskin


___
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH] drivemap fixes

2009-06-05 Thread Vladimir 'phcoder' Serbinenko
Hello. As suggested by Javier Martín I move this to a new thread. This
patch fixes some problems with determining bios number of a disk.
biosnum is in boot.mod because it's where it will cause the least of
possible core.img increase (3 of 5 loaders on pc need biosnum).
Thisforced to move boot.mod to platform-specific files but this
inflexibility of build system is a subject for another patch

-- 
Regards
Vladimir 'phcoder' Serbinenko
diff --git a/commands/i386/pc/drivemap.c b/commands/i386/pc/drivemap.c
index 898fb51..92781a0 100644
--- a/commands/i386/pc/drivemap.c
+++ b/commands/i386/pc/drivemap.c
@@ -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);
diff --git a/commands/i386/pc/drivemap_int13h.S b/commands/i386/pc/drivemap_int13h.S
index 7a3e8e7..ba31a9c 100644
--- a/commands/i386/pc/drivemap_int13h.S
+++ b/commands/i386/pc/drivemap_int13h.S
@@ -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 @@ 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
+
+postamble:	
+	
+	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 postamble
+	
 /* 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)
diff --git a/conf/common.rmk b/conf/common.rmk
index 3e59c3a..b328bc4 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -353,19 +353,13 @@ 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	\
-	gptsync.mod
+	pcpart.mod memrw.mod normal.mod sh.mod lua.mod gptsync.mod
 
 # For gptsync.mod.
 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)
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index 2f768c0..483f279 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -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