All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Franke <Christian.Franke@t-online.de>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: Re: [PATCH] grub2 for Cygwin
Date: Sun, 21 Oct 2007 15:07:07 +0200	[thread overview]
Message-ID: <471B4EFB.6020009@t-online.de> (raw)
In-Reply-To: <20071020233721.GA9939@thorin>

[-- Attachment #1: Type: text/plain, Size: 832 bytes --]

Robert Millan wrote:
> On Tue, Oct 16, 2007 at 02:03:35PM +0200, Christian Franke wrote:
>   
>> A patch vs. current CVS (cvs co -D "2007-10-16 UTC" ...) is available
>> here:
>> http://franke.dvrdns.org/cygwin/grub/grub2-20071016-cygwin.patch
>> A proposed changelog entry is located in the patch itself
>> (Changelog.cygwin).
>>     
>
> Could you send it as an attachment?  This way it's easier to comment on
> it contextualy.
>
>   

I didn't want to send a ~45KB attachment in my first mail to this list ;-)
Patch is attached.


>> - "terminal gfxterm", "videotest" and "vbetest" do not work. Characters
>> are not visible. This could also be reproduced when compiled on Linux.
>>     
>
> Did you load a font file?  See http://grub.enbug.org/gfxterm
>
>   

With the font is works. Sorry for the noise.

regards,
  Christian


[-- Attachment #2: grub2-20071016-cygwin.patch --]
[-- Type: text/x-patch, Size: 43415 bytes --]

diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/ChangeLog.cygwin grub2/ChangeLog.cygwin
--- grub2.orig/ChangeLog.cygwin	1970-01-01 01:00:00.000000000 +0100
+++ grub2/ChangeLog.cygwin	2007-10-16 12:29:52.000000000 +0200
@@ -0,0 +1,100 @@
+
+	Patch from Christian Franke <franke@computer.org>:
+
+	* Makefile.in: Add autoconf replacements TARGET_IMG_LDSCRIPT,
+	TARGET_IMG_LDFLAGS, TARGET_MOD_COPY and EXEEXT.
+
+	* aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Replace -Wl,-N by
+	TARGET_IMG_LDFLAGS_AC.
+	(grub_CHECK_STACK_ARG_PROBE): New function.
+
+	* configure.ac: Add check for linker script "conf/${host}-img-ld.c"
+	to set TARGET_IMG_LD* accordingly.
+	Add check for Cygwin to set TARGET_MOD_OBJCOPY accordingly.
+	Use TARGET_IMG_LDFLAGS to check start, bss_start, end symbols.
+
+	* genkernsyms.sh.in: Handle HAVE_ASM_USCORE case.
+
+	* genmk.rb: Add TARGET_MOD_OBJCOPY step to convert native linker
+	output format to ELF.
+	Handle HAVE_ASM_USCORE case in strip command.
+	Add EXEEXT to CLEANFILES.
+
+	* conf/i386-pc.rmk: Replace -Wl,-N by TARGET_IMG_LDFLAGS.
+
+	* conf/i686-pc-cygwin-ld-img.sc: New linker script.
+
+	* disk/host.c (grub_host_open): Add check for "host". This fixes
+	the problem that grub-emu does not find partitions.
+
+	* include/grub/dl.h: Remove .previous, gas supports this only
+	for ELF format.
+
+	* include/grub/i386/pc/init.h (struct grub_machine_mmap_entry):
+	Add attribute packed, gcc 3.4.4 on Cygwin aligns this
+	to 64 bit boundary by default.
+	Add compile time assert to check packing.
+
+	* include/grub/symbol.h (#define FUNCTION/VARIABLE): Remove .type
+	for Cygwin, gas supports this only for ELF format.
+
+	* kern/dl.c (grub_dl_resolve_symbol): Handle HAVE_ASM_USCORE case,
+	ignore leading underscore.
+	(grub_dl_register_symbol): Likewise.
+	(grub_dl_resolve_symbols): Likewise.
+	Add check for grub_mod_init/fini for symbols without type. 
+	(grub_dl_resolve_dependencies): Add check for trailing nullbytes
+	in symbol table.
+
+	* kern/i386/dl.c (fix_pc_rel_relocation): New function to fix
+	bad PC relative relocation produced by Cygwin's objcopy.
+	(grub_arch_dl_relocate_symbols): Add fix of PC relative relocation.
+	Add Warning on unknown relocation type.
+
+	* kern/i386/pc/init.c (addr_is_valid): New function.
+	(add_mem_region): Add memory existence check.
+	(grub_machine_init): Fix evaluation of eisa_mmap.
+
+	* util/biosdisk.c: Add Cygwin specific includes.
+	(grub_util_biosdisk_open): Add Cygwin support.
+	(grub_util_biosdisk_get_grub_dev): Likewise.
+
+	* util/console.c (grub_ncurses_getkey): Change curses KEY_* mapping,
+	now return control chars instead of GRUB_CONSOLE_KEY_* konstants.
+	This fixes the problem that function keys did not work in grub-emu.
+
+	* util/getroot.c: Add Cygwin specific incldes.
+	(get_win32_path): New Cygwin specific function.
+	(grub_get_prefix): Add conversion from Cygwin to native path.
+	(get_serial): New Cygwin specific function.
+	(find_root_device): Likewise.
+	(grub_util_get_grub_dev): Disable /dev/mapper check on Cygwin.
+
+	* util/grub-emu.c: Replace argp.h by getopt.h.
+	(parse_opt): Remove.
+	(usage): New function.
+	(main): Replace argp_parse() by getopt_long().
+	Rename argument variables accordingly.
+	Add missing "(..)" for root_dev in prefix.
+
+	* util/grub-mkdevicemap.c (get_floppy_disk_name): Add Cygwin device
+	name.
+	(get_ide_disk_name): Likewise.
+	(get_scsi_disk_name): Likewise.
+	(check_device): Add static.
+	Return error instead of success on empty string.
+	(make_device_map): Move label inside linux specific code to
+	prevent compiler warning.
+
+	* util/grub-probe.c (#define PRINT_*): Change to bitmasks
+	to allow multiple '-t type' options.
+	Add PRINT_PREFIX (-t prefix)
+	(probe): Likewise.
+	types now passed as parameter.
+	(main): Likewise.
+
+	* util/hostfs.c (is_dir): New function.
+	(grub_hostfs_dir):  Handle missing dirent.d_type case.
+	(grub_hostfs_label): Clear label pointer. This fixes a crash
+	of grub-emu on "ls (host)".
+
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/Makefile.in grub2/Makefile.in
--- grub2.orig/Makefile.in	2007-06-11 08:26:17.000000000 +0200
+++ grub2/Makefile.in	2007-10-12 22:43:29.000000000 +0200
@@ -67,6 +67,10 @@ TARGET_CFLAGS = @TARGET_CFLAGS@
 TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I. -Iinclude -I$(srcdir)/include \
 	-Wall -W
 TARGET_LDFLAGS = @TARGET_LDFLAGS@
+TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@
+TARGET_IMG_LDFLAGS = @TARGET_IMG_LDFLAGS@
+TARGET_MOD_COPY = @TARGET_MOD_COPY@
+EXEEXT = @EXEEXT@
 OBJCOPY = @OBJCOPY@
 STRIP = @STRIP@
 NM = @NM@
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/aclocal.m4 grub2/aclocal.m4
--- grub2.orig/aclocal.m4	2007-02-03 12:36:13.000000000 +0100
+++ grub2/aclocal.m4	2007-10-12 22:47:20.000000000 +0200
@@ -57,7 +57,7 @@ else
 fi
 grub_cv_prog_objcopy_absolute=yes
 for link_addr in 2000 8000 7C00; do
-  if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
+  if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
   else
     AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
   fi
@@ -362,3 +362,19 @@ else
   AC_MSG_RESULT([no])
 [fi]
 ])
+
+dnl Check if the C compiler supports `-mstack-arg-probe' (Cygwin).
+AC_DEFUN(grub_CHECK_STACK_ARG_PROBE,[
+[# Smashing stack arg probe.
+sap_possible=yes]
+AC_MSG_CHECKING([whether `$CC' accepts `-mstack-arg-probe'])
+AC_LANG_CONFTEST([[void foo (void) { volatile char a[8]; a[3]; }]])
+[if eval "$ac_compile -S -mstack-arg-probe -o conftest.s" 2> /dev/null; then]
+  AC_MSG_RESULT([yes])
+  [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
+  rm -f conftest.s
+else
+  sap_possible=no]
+  AC_MSG_RESULT([no])
+[fi]
+])
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/conf/i386-pc.rmk grub2/conf/i386-pc.rmk
--- grub2.orig/conf/i386-pc.rmk	2007-08-29 12:39:42.000000000 +0200
+++ grub2/conf/i386-pc.rmk	2007-10-12 22:47:52.000000000 +0200
@@ -10,17 +10,17 @@ pkgdata_IMAGES = boot.img diskboot.img k
 # For boot.img.
 boot_img_SOURCES = boot/i386/pc/boot.S
 boot_img_ASFLAGS = $(COMMON_ASFLAGS)
-boot_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
+boot_img_LDFLAGS = -nostdlib $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00
 
 # For pxeboot.img
 pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S
 pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS)
-pxeboot_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
+pxeboot_img_LDFLAGS = -nostdlib $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00
 
 # For diskboot.img.
 diskboot_img_SOURCES = boot/i386/pc/diskboot.S
 diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
-diskboot_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,8000
+diskboot_img_LDFLAGS = -nostdlib $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,8000
 
 # For kernel.img.
 kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \
@@ -38,7 +38,7 @@ kernel_img_HEADERS = arg.h boot.h cache.
 	machine/vbe.h
 kernel_img_CFLAGS = $(COMMON_CFLAGS)
 kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,8200 $(COMMON_CFLAGS)
+kernel_img_LDFLAGS = -nostdlib $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,8200 $(COMMON_CFLAGS)
 
 MOSTLYCLEANFILES += symlist.c kernel_syms.lst
 DEFSYMFILES += kernel_syms.lst
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/conf/i686-pc-cygwin-img-ld.sc grub2/conf/i686-pc-cygwin-img-ld.sc
--- grub2.orig/conf/i686-pc-cygwin-img-ld.sc	1970-01-01 01:00:00.000000000 +0100
+++ grub2/conf/i686-pc-cygwin-img-ld.sc	2007-10-12 22:50:06.000000000 +0200
@@ -0,0 +1,53 @@
+/* Linker script to create grub .img files on Cygwin */
+
+SECTIONS
+{
+  .text :
+  {
+    start = . ;
+    *(.text)
+    etext = . ;
+  }
+  .data :
+  {
+    __data_start__ = . ;
+    *(.data)
+    __data_end__ = . ;
+  }
+  .rdata :
+  {
+    __rdata_start__ = . ;
+    *(.rdata)
+    __rdata_end__ = . ;
+  }
+  .pdata :
+  {
+    *(.pdata)
+    edata = . ;
+  }
+  .bss :
+  {
+    __bss_start__ = . ;
+    *(.bss)
+    __common_start__ = . ;
+    *(COMMON)
+    __bss_end__ = . ;
+  }
+  .edata :
+  {
+    *(.edata)
+    end = . ;
+  }
+  .stab :
+  {
+    *(.stab)
+  }
+  .stabstr :
+  {
+    *(.stabstr)
+  }
+}
+
+ASSERT("__rdata_end__"=="__bss_start__", ".pdata not empty")
+ASSERT("__bss_end__"  =="end"          , ".edata not empty")
+
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/configure.ac grub2/configure.ac
--- grub2.orig/configure.ac	2007-05-17 21:03:42.000000000 +0200
+++ grub2/configure.ac	2007-10-13 14:44:59.000000000 +0200
@@ -155,6 +155,32 @@ AC_CHECK_FUNCS(posix_memalign memalign)
 # Check for target programs.
 #
 
+
+# Use linker script if present, otherwise use builtin -N script
+AC_MSG_CHECKING([for option to link raw image])
+if test -f "${srcdir}/conf/${host}-img-ld.sc"; then
+  TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${host}-img-ld.sc"
+  TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
+  TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${host}-img-ld.sc"
+else
+  TARGET_IMG_LDSCRIPT=
+  TARGET_IMG_LDFLAGS='-Wl,-N'
+  TARGET_IMG_LDFLAGS_AC='-Wl,-N'
+fi
+AC_SUBST(TARGET_IMG_LDSCRIPT)
+AC_SUBST(TARGET_IMG_LDFLAGS)
+AC_MSG_RESULT([$TARGET_IMG_LDFLAGS_AC])
+
+# For platforms where ELF is not the default link format
+AC_MSG_CHECKING([for command to convert module to ELF format])
+if test "x$host" = "xi686-pc-cygwin"; then
+  TARGET_MOD_COPY='$(OBJCOPY) -O elf32-i386'
+else
+  TARGET_MOD_COPY='cp -f'
+fi
+AC_SUBST(TARGET_MOD_COPY)
+AC_MSG_RESULT([$TARGET_MOD_COPY])
+
 # For cross-compiling.
 if test "x$target" != "x$host"; then
   # XXX this depends on the implementation of autoconf!
@@ -239,6 +265,12 @@ grub_CHECK_STACK_PROTECTOR
 if [ x"$ssp_possible" = xyes ]; then
   TARGET_CFLAGS=$TARGET_CFLAGS\ -fno-stack-protector
 fi]
+grub_CHECK_STACK_ARG_PROBE
+[# Cygwin's GCC uses alloca() to probe the stackframe on static
+# stack allocations above some threshold
+if [ x"$sap_possible" = xyes ]; then
+  TARGET_CFLAGS=$TARGET_CFLAGS\ -mno-stack-arg-probe
+fi]
 
 AC_SUBST(TARGET_CFLAGS)
 AC_SUBST(TARGET_CPPFLAGS)
@@ -254,9 +286,14 @@ LDFLAGS="$TARGET_LDFLAGS"
 grub_PROG_OBJCOPY_ABSOLUTE
 grub_ASM_USCORE
 if test "x$target_cpu" = xi386; then
+  if test ! -z "$TARGET_IMG_LDSCRIPT"; then
+    # Check symbols provided by linker script
+    CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100"
+  fi
   grub_CHECK_START_SYMBOL
   grub_CHECK_BSS_START_SYMBOL
   grub_CHECK_END_SYMBOL
+  CFLAGS="$TARGET_CFLAGS"
   grub_I386_ASM_PREFIX_REQUIREMENT
   grub_I386_ASM_ADDR32
   grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/disk/host.c grub2/disk/host.c
--- grub2.orig/disk/host.c	2007-08-02 19:24:05.000000000 +0200
+++ grub2/disk/host.c	2007-10-13 15:11:18.000000000 +0200
@@ -34,8 +34,11 @@ grub_host_iterate (int (*hook) (const ch
 }
 
 static grub_err_t
-grub_host_open (const char *name __attribute((unused)), grub_disk_t disk)
+grub_host_open (const char *name, grub_disk_t disk)
 {
+  if (grub_strcmp(name, "host"))
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk");
+
   disk->total_sectors = 0;
   disk->id = (int) "host";
   
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/genkernsyms.sh.in grub2/genkernsyms.sh.in
--- grub2.orig/genkernsyms.sh.in	2006-07-12 22:42:52.000000000 +0200
+++ grub2/genkernsyms.sh.in	2007-10-06 12:59:29.000000000 +0200
@@ -16,9 +16,12 @@
 srcdir=@srcdir@
 CC="@CC@"
 
+u=
+grep "^#define HAVE_ASM_USCORE" config.h >/dev/null 2>&1 && u="_"
+
 $CC -DGRUB_SYMBOL_GENERATOR=1 -E -I. -Iinclude -I$srcdir/include $* \
   | grep -v '^#' \
   | sed -n \
-        -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/\1 kernel/;p;}' \
-        -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/\1 kernel/;p;}' \
+        -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \
+        -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \
   | sort -u
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/genmk.rb grub2/genmk.rb
--- grub2.orig/genmk.rb	2007-08-29 12:39:42.000000000 +0200
+++ grub2/genmk.rb	2007-10-12 22:46:05.000000000 +0200
@@ -114,8 +114,10 @@ UNDSYMFILES += #{undsym}
 
 #{@name}: #{pre_obj} #{mod_obj}
 	-rm -f $@
-	$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
-	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+	$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.tmp $^
+	$(TARGET_MOD_COPY) $@.tmp $@ || (rm -f $@.tmp; exit 1)
+	rm -f $@.tmp
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
 
 #{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str}
 	-rm -f $@
@@ -186,7 +188,7 @@ class Utility
     deps = objs.collect {|obj| obj.suffix('d')}
     deps_str = deps.join(' ');
 
-    "CLEANFILES += #{@name} #{objs_str}
+    "CLEANFILES += #{@name}$(EXEEXT) #{objs_str}
 MOSTLYCLEANFILES += #{deps_str}
 
 #{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str}
Files grub2.orig/grub2-floppy.img and grub2/grub2-floppy.img differ
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/include/grub/dl.h grub2/include/grub/dl.h
--- grub2.orig/include/grub/dl.h	2007-07-22 01:32:21.000000000 +0200
+++ grub2/include/grub/dl.h	2007-10-15 23:07:35.000000000 +0200
@@ -40,11 +40,12 @@ grub_##name##_fini (void) { grub_mod_fin
 static void \
 grub_mod_fini (void)
 
+/* Note: .previous not supported for non-ELF targets */
 #define GRUB_MOD_NAME(name)	\
-__asm__ (".section .modname,\"S\"\n.string \"" #name "\"\n.previous")
+__asm__ (".section .modname\n.string \"" #name "\"\n")
 
 #define GRUB_MOD_DEP(name)	\
-__asm__ (".section .moddeps,\"S\"\n.string \"" #name "\"\n.previous")
+__asm__ (".section .moddeps\n.string \"" #name "\"\n")
 
 struct grub_dl_segment
 {
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/include/grub/i386/pc/init.h grub2/include/grub/i386/pc/init.h
--- grub2.orig/include/grub/i386/pc/init.h	2007-07-22 01:32:23.000000000 +0200
+++ grub2/include/grub/i386/pc/init.h	2007-10-13 21:25:24.000000000 +0200
@@ -40,10 +40,14 @@ grub_uint32_t grub_get_eisa_mmap (void);
 struct grub_machine_mmap_entry
 {
   grub_uint32_t size;
-  grub_uint64_t addr;
+  grub_uint64_t addr; /* must be at offset 4, see startup.S */ 
   grub_uint64_t len;
   grub_uint32_t type;
-};
+} __attribute__((packed));
+
+/* Compile time assert to check packing */
+typedef char ASSERT_sizeof_grub_machine_mmap_entry[
+  sizeof (struct grub_machine_mmap_entry) == 4+8+8+4 ? 1 : -1];
 
 /* Get a memory map entry. Return next continuation value. Zero means
    the end.  */
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/include/grub/symbol.h grub2/include/grub/symbol.h
--- grub2.orig/include/grub/symbol.h	2007-07-22 01:32:22.000000000 +0200
+++ grub2/include/grub/symbol.h	2007-10-15 23:08:13.000000000 +0200
@@ -28,8 +28,14 @@
 # define EXT_C(sym)	sym
 #endif
 
+#ifndef __CYGWIN__
 #define FUNCTION(x)	.globl EXT_C(x) ; .type EXT_C(x), "function" ; EXT_C(x):
 #define VARIABLE(x)	.globl EXT_C(x) ; .type EXT_C(x), "object" ; EXT_C(x):
+#else
+/* .type not supported for non-ELF targets. XXX: Check this in configure? */
+#define FUNCTION(x)	.globl EXT_C(x) ; EXT_C(x):
+#define VARIABLE(x)	.globl EXT_C(x) ; EXT_C(x):
+#endif
 
 /* Mark an exported symbol.  */
 #ifndef GRUB_SYMBOL_GENERATOR
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/kern/dl.c grub2/kern/dl.c
--- grub2.orig/kern/dl.c	2007-07-22 01:32:26.000000000 +0200
+++ grub2/kern/dl.c	2007-10-15 22:52:05.000000000 +0200
@@ -156,6 +156,9 @@ grub_dl_resolve_symbol (const char *name
 {
   grub_symbol_t sym;
 
+  if (*name == '_')
+    name++;
+
   for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next)
     if (grub_strcmp (sym->name, name) == 0)
       return sym->addr;
@@ -169,6 +172,11 @@ grub_dl_register_symbol (const char *nam
 {
   grub_symbol_t sym;
   unsigned k;
+
+  /* Ignore leading underscore used for C symbols.
+     Done at runtime to allow loading modules compiled on other OS. */
+  if (*name == '_')
+    name++;
   
   sym = (grub_symbol_t) grub_malloc (sizeof (*sym));
   if (! sym)
@@ -347,6 +355,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, 
       unsigned char type = ELF_ST_TYPE (sym->st_info);
       unsigned char bind = ELF_ST_BIND (sym->st_info);
       const char *name = str + sym->st_name;
+      int check_mod_func = 0;
       
       switch (type)
 	{
@@ -359,6 +368,12 @@ grub_dl_resolve_symbols (grub_dl_t mod, 
 		return grub_error (GRUB_ERR_BAD_MODULE,
 				   "the symbol `%s' not found", name);
 	    }
+	  else if (sym->st_name != 0 && bind == STB_LOCAL)
+	    { /* static functions have no type if initial format was not ELF */
+	      sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
+								    sym->st_shndx);
+	      check_mod_func = 1;
+	    }
 	  else
 	    sym->st_value = 0;
 	  break;
@@ -374,14 +389,11 @@ grub_dl_resolve_symbols (grub_dl_t mod, 
 	case STT_FUNC:
 	  sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
 								sym->st_shndx);
-	  if (bind != STB_LOCAL)
+	  if (bind == STB_LOCAL)
+	    check_mod_func = 1;
+	  else	
 	    if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
 	      return grub_errno;
-	  
-	  if (grub_strcmp (name, "grub_mod_init") == 0)
-	    mod->init = (void (*) (grub_dl_t)) sym->st_value;
-	  else if (grub_strcmp (name, "grub_mod_fini") == 0)
-	    mod->fini = (void (*) (void)) sym->st_value;
 	  break;
 
 	case STT_SECTION:
@@ -397,6 +409,15 @@ grub_dl_resolve_symbols (grub_dl_t mod, 
 	  return grub_error (GRUB_ERR_BAD_MODULE,
 			     "unknown symbol type `%d'", (int) type);
 	}
+      if (check_mod_func)
+        {
+	  if (*name == '_')
+	    name++;
+	  if (grub_strcmp (name, "grub_mod_init") == 0)
+	    mod->init = (void (*) (grub_dl_t)) sym->st_value;
+	  else if (grub_strcmp (name, "grub_mod_fini") == 0)
+	    mod->fini = (void (*) (void)) sym->st_value;
+        }
     }
 
   return GRUB_ERR_NONE;
@@ -454,7 +475,7 @@ grub_dl_resolve_dependencies (grub_dl_t 
 	const char *name = (char *) e + s->sh_offset;
 	const char *max = name + s->sh_size;
 
-	while (name < max)
+	while (name < max && *name) /* segment may contain trailing 0 */
 	  {
 	    grub_dl_t m;
 	    grub_dl_dep_t dep;
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/kern/i386/dl.c grub2/kern/i386/dl.c
--- grub2.orig/kern/i386/dl.c	2007-07-22 01:32:26.000000000 +0200
+++ grub2/kern/i386/dl.c	2007-10-16 11:16:45.000000000 +0200
@@ -37,6 +37,34 @@ grub_arch_dl_check_header (void *ehdr)
   return GRUB_ERR_NONE;
 }
 
+
+/* Fix PC relative relocation. Cygwin's objcopy does not
+adjust the addent when converting from pei-i386 to elf32-i386.
+This code is unconditionally included because is allows to
+load modules compiled on Cygwin from a GRUB kernel compiled
+on another OS and vice versa (tested on Linux with gcc 4.1.3). 
+XXX: This hack should be removed when a fix for objcopy is
+available */
+
+static int
+fix_pc_rel_relocation (Elf32_Word *addr)
+{
+  /* to be safe, check instruction first */
+  const unsigned char * pc = (const unsigned char *)addr - 1;
+  if (!(*pc == 0xe8/*call*/ || *pc == 0xe9/*jmp*/))
+    return grub_error (GRUB_ERR_BAD_MODULE, "unknown pc-relative instruction %02x", *pc);
+  /* check and adjust offset */
+  if (*addr != (Elf32_Word)-4)
+    {
+      if (*addr != 0)
+	return grub_error (GRUB_ERR_BAD_MODULE, "pc-relative relocation base is not zero");
+      *addr = (Elf32_Word)-4;
+    }
+  return GRUB_ERR_NONE;
+}
+/* #endif */
+
+
 /* Relocate symbols.  */
 grub_err_t
 grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
@@ -99,9 +127,15 @@ grub_arch_dl_relocate_symbols (grub_dl_t
 		    break;
 
 		  case R_386_PC32:
+		    if (fix_pc_rel_relocation (addr))
+		      return grub_errno;
 		    *addr += (sym->st_value - (Elf32_Word) seg->addr
 			      - rel->r_offset);
 		    break;
+
+		  default:
+		    return grub_printf ("Warning: unknown ELF relocation type %x.",
+				    ELF32_R_TYPE (rel->r_info));
 		  }
 	      }
 	  }
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/kern/i386/pc/init.c grub2/kern/i386/pc/init.c
--- grub2.orig/kern/i386/pc/init.c	2007-09-03 22:33:20.000000000 +0200
+++ grub2/kern/i386/pc/init.c	2007-10-15 22:53:25.000000000 +0200
@@ -77,6 +77,19 @@ make_install_device (void)
   return grub_prefix;
 }
 
+/* Check memory address */
+static int
+addr_is_valid (grub_addr_t addr)
+{
+  volatile unsigned char * p = (volatile unsigned char *)addr;
+  unsigned char x, y;
+  x = *p;
+  *p = x ^ 0xcf;
+  y = *p;
+  *p = x;
+  return y == (x ^ 0xcf);
+}
+
 /* Add a memory region.  */
 static void
 add_mem_region (grub_addr_t addr, grub_size_t size)
@@ -85,6 +98,9 @@ add_mem_region (grub_addr_t addr, grub_s
     /* Ignore.  */
     return;
 
+  if (!(addr + size > addr && addr_is_valid (addr) && addr_is_valid (addr+size-1)))
+    grub_fatal ("invalid memory region %p - %p", (char*)addr, (char*)addr+size-1);
+
   mem_regions[num_regions].addr = addr;
   mem_regions[num_regions].size = size;
   num_regions++;
@@ -193,13 +209,8 @@ grub_machine_init (void)
 
       if (eisa_mmap)
 	{
-	  if ((eisa_mmap & 0xFFFF) == 0x3C00)
-	    add_mem_region (0x100000, (eisa_mmap << 16) + 0x100000 * 15);
-	  else
-	    {
-	      add_mem_region (0x100000, (eisa_mmap & 0xFFFF) << 10);
-	      add_mem_region (0x1000000, eisa_mmap << 16);
-	    }
+	  add_mem_region (0x100000, (eisa_mmap & 0xFFFF) << 10);
+	  add_mem_region (0x1000000, eisa_mmap & ~0xFFFF);
 	}
       else
 	add_mem_region (0x100000, grub_get_memsize (1) << 10);
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/util/biosdisk.c grub2/util/biosdisk.c
--- grub2.orig/util/biosdisk.c	2007-07-22 01:32:31.000000000 +0200
+++ grub2/util/biosdisk.c	2007-10-15 22:56:23.000000000 +0200
@@ -76,6 +76,11 @@ struct hd_geometry
 # endif /* ! LOOP_MAJOR */
 #endif /* __linux__ */
 
+#ifdef __CYGWIN__
+# include <sys/ioctl.h> /* ioctl */
+# include <cygwin/fs.h> /* BLKGETSIZE64 */
+#endif
+
 static char *map[256];
 
 #ifdef __linux__
@@ -161,7 +166,7 @@ grub_util_biosdisk_open (const char *nam
   disk->id = drive;
 
   /* Get the size.  */
-#ifdef __linux__
+#if defined(__linux__) || defined(__CYGWIN__)
   {
     unsigned long long nr;
     int fd;
@@ -663,6 +668,12 @@ get_os_disk (const char *os_dev)
     }
   return path;
 
+#elif defined(__CYGWIN__)
+  path = xstrdup (os_dev); (void)p;
+  if (strncmp("/dev/sd", path, 7) == 0 && 'a' <= path[7] && path[7] <= 'z')
+    path[8] = 0;
+  return path;
+
 #else
 # warning "The function `get_os_disk' might not work on your OS correctly."
   return xstrdup (os_dev);
@@ -849,6 +860,15 @@ grub_util_biosdisk_get_grub_dev (const c
     
     return make_device_name (drive, dos_part, bsd_part);
   }
+
+#elif defined(__CYGWIN__)
+  int dos_part = -1, nc = -1;
+  sscanf (os_dev, "/dev/sd%*[a-z]%d%n", &dos_part, &nc);
+  if (nc != (int)strlen (os_dev))
+    dos_part = -1;
+  else
+    dos_part--;
+  return make_device_name (drive, dos_part, -1);
   
 #else
 # warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly."
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/util/console.c grub2/util/console.c
--- grub2.orig/util/console.c	2007-07-22 01:32:31.000000000 +0200
+++ grub2/util/console.c	2007-10-13 16:13:46.000000000 +0200
@@ -161,53 +161,59 @@ grub_ncurses_getkey (void)
       c = getch ();
     }
 
+  /* XXX: return GRUB_CONSOLE_KEY_* does not work here,
+     grub_cmdline_get() does not check for these constants.
+     At least on i386-pc, GRUB_CONSOLE_KEY_* are in fact keyboard
+     scancodes which are converted into control chars by
+     grub_console_getkey(). */
+
   switch (c)
     {
     case KEY_LEFT:
-      c = GRUB_CONSOLE_KEY_LEFT;
+      c = 2; /*GRUB_CONSOLE_KEY_LEFT*/
       break;
 
     case KEY_RIGHT:
-      c = GRUB_CONSOLE_KEY_RIGHT;
+      c = 6; /*GRUB_CONSOLE_KEY_RIGHT*/
       break;
       
     case KEY_UP:
-      c = GRUB_CONSOLE_KEY_UP;
+      c = 16; /*GRUB_CONSOLE_KEY_UP*/
       break;
 
     case KEY_DOWN:
-      c = GRUB_CONSOLE_KEY_DOWN;
+      c = 14; /*GRUB_CONSOLE_KEY_DOWN*/
       break;
 
     case KEY_IC:
-      c = GRUB_CONSOLE_KEY_IC;
+      c = 24; /*GRUB_CONSOLE_KEY_IC*/
       break;
 
     case KEY_DC:
-      c = GRUB_CONSOLE_KEY_DC;
+      c = 4; /*GRUB_CONSOLE_KEY_DC*/
       break;
 
     case KEY_BACKSPACE:
       /* XXX: For some reason ncurses on xterm does not return
 	 KEY_BACKSPACE.  */
     case 127: 
-      c = GRUB_CONSOLE_KEY_BACKSPACE;
+      c = 8; /*GRUB_CONSOLE_KEY_BACKSPACE*/;
       break;
 
     case KEY_HOME:
-      c = GRUB_CONSOLE_KEY_HOME;
+      c = 1; /*GRUB_CONSOLE_KEY_HOME*/
       break;
 
     case KEY_END:
-      c = GRUB_CONSOLE_KEY_END;
+      c = 5; /*GRUB_CONSOLE_KEY_END*/
       break;
 
     case KEY_NPAGE:
-      c = GRUB_CONSOLE_KEY_NPAGE;
+      c = 3; /*GRUB_CONSOLE_KEY_NPAGE*/
       break;
 
     case KEY_PPAGE:
-      c = GRUB_CONSOLE_KEY_PPAGE;
+      c = 7; /*GRUB_CONSOLE_KEY_PPAGE*/
       break;
     }
 
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/util/getroot.c grub2/util/getroot.c
--- grub2.orig/util/getroot.c	2007-07-22 01:32:31.000000000 +0200
+++ grub2/util/getroot.c	2007-10-13 21:45:51.000000000 +0200
@@ -21,6 +21,10 @@
 #include <unistd.h>
 #include <string.h>
 #include <dirent.h>
+#ifdef __CYGWIN__
+#include <sys/fcntl.h>
+#include <sys/cygwin.h>
+#endif
 
 #include <grub/util/misc.h>
 #include <grub/util/biosdisk.h>
@@ -63,6 +67,29 @@ xgetcwd (void)
   return path;
 }
 
+#ifdef __CYGWIN__
+/* Convert Cygwin path to Win32 path,
+remove drive, convert backslashes */
+static char *
+get_win32_path (const char *path)
+{
+  int i, len;
+  char winpath[1024];
+  cygwin_conv_to_win32_path(path, winpath);
+  len = strlen(winpath);
+  if (len > 2 && winpath[1] == ':')
+    {
+      len -= 2;
+      memmove (winpath, winpath + 2, len + 1);
+    }
+  for (i = 0; i < len; i++)
+    if (winpath[i] == '\\')
+      winpath[i] = '/';
+  return xstrdup (winpath);
+  
+}
+#endif
+
 char *
 grub_get_prefix (const char *dir)
 {
@@ -119,10 +146,23 @@ grub_get_prefix (const char *dir)
   free (abs_dir);
   free (prev_dir);
 
+#ifdef __CYGWIN__
+  /* GRUB does not know Cygwin's mounts, convert to Win32 path */
+  grub_util_info ("Cygwin prefix = %s", prefix);
+  {
+    char * wprefix = get_win32_path (prefix);
+    free (prefix);
+    prefix = wprefix;
+  }
+#endif
+
   grub_util_info ("prefix = %s", prefix);
   return prefix;
 }
 
+
+#ifndef __CYGWIN__
+
 static char *
 find_root_device (const char *dir, dev_t dev)
 {
@@ -215,6 +255,69 @@ find_root_device (const char *dir, dev_t
   return 0;
 }
 
+#else /* __CYGWIN__ */
+
+/* Cygwin returns the partition serial number in stat.st_dev,
+which is never identical to the device number of the emulated
+/dev/sdX device. Therefore, the above does not work and we
+search a partion with the serial instead. */
+/* XXX: There is probably a better way doing this */
+
+/* Read drive/partition serial number from mbr/boot sector
+   return 0 on read error, ~0 on unknown serial */
+static unsigned
+getserial (const char *os_dev, int mbr)
+{
+  unsigned char buf[0x200];
+  int fd, n;
+  fd = open (os_dev, O_RDONLY);
+  if (fd < 0)
+    return 0;
+  n = read (fd, buf, sizeof(buf));
+  close (fd);
+  if (n != sizeof(buf))
+    return 0;
+  if (!(buf[0x1fe] == 0x55 && buf[0x1ff] == 0xaa))
+    return ~0;
+  if (mbr)
+    n = 0x1b8;
+  else if (memcmp (buf+0x03, "NTFS", 4) == 0)
+    n = 0x048;
+  else if (memcmp (buf+0x52, "FAT32", 5) == 0)
+    n = 0x043;
+  else if (memcmp (buf+0x36, "FAT", 3) == 0)
+    n = 0x027;
+  else
+    return ~0;
+  return *(unsigned *)(buf + n);
+}
+
+/* Find device name for partition with serial number dev */
+static char *
+find_root_device (const char *dir, dev_t dev)
+{
+  int d, p;
+  char devpath[sizeof("/dev/sda15")+13];
+  (void)dir;
+  for (d = 'a'; d <= 'z'; d++) {
+    sprintf (devpath, "/dev/sd%c", d);
+    if (getserial (devpath, 1) == 0)
+      continue;
+    for (p = 1; p <= 15; p++) {
+      unsigned ser;
+      sprintf (devpath, "/dev/sd%c%d", d, p);
+      ser = getserial (devpath, 0);
+      if (ser == 0)
+        break;
+      if (ser != (unsigned)~0 && dev == (dev_t)ser)
+  	return xstrdup (devpath);
+    }
+  }
+  return 0;
+}
+
+#endif /* __CYGWIN__ */
+
 char *
 grub_guess_root_device (const char *dir)
 {
@@ -242,6 +345,7 @@ grub_guess_root_device (const char *dir)
 char *
 grub_util_get_grub_dev (const char *os_dev)
 {
+#ifndef __CYGWIN__
   /* Check for LVM.  */
   if (!strncmp (os_dev, "/dev/mapper/", 12))
     {
@@ -307,6 +411,7 @@ grub_util_get_grub_dev (const char *os_d
 
       return grub_dev;
     }
+#endif /* !__CYGWIN__ */
 
   /* If it's not RAID or LVM, it should be a biosdisk.  */
   return grub_util_biosdisk_get_grub_dev (os_dev);
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/util/grub-emu.c grub2/util/grub-emu.c
--- grub2.orig/util/grub-emu.c	2007-08-02 19:24:06.000000000 +0200
+++ grub2/util/grub-emu.c	2007-10-15 22:57:39.000000000 +0200
@@ -18,7 +18,7 @@
 
 #include <stdlib.h>
 #include <sys/stat.h>
-#include <argp.h>
+#include <getopt.h>
 #include <string.h>
 #include <signal.h>
 #include <sys/types.h>
@@ -90,104 +90,109 @@ grub_machine_fini (void)
 }
 \f
 
-const char *argp_program_version = PACKAGE_STRING;
-const char *argp_program_bug_address = PACKAGE_BUGREPORT;
-static char doc[] = "GRUB emulator";
-
-static struct argp_option options[] = {
-  {"root-device", 'r', "DEV",  0, "use DEV as the root device [default=guessed]", 0},
-  {"device-map",  'm', "FILE", 0, "use FILE as the device map", 0},
-  {"directory",   'd', "DIR",  0, "use GRUB files in the directory DIR", 0},
-  {"verbose",     'v', 0     , 0, "print verbose messages", 0},
-  {"hold",        'H', "SECONDS", OPTION_ARG_OPTIONAL, "wait until a debugger will attach", 0},
-  { 0, 0, 0, 0, 0, 0 }
-};
-
-struct arguments
-{
-  char *root_dev;
-  char *dev_map;
-  char *dir;
-  int hold;
-};
-
-static error_t
-parse_opt (int key, char *arg, struct argp_state *state)
-{
-  struct arguments *args = state->input;
-  
-  switch (key)
-    {
-    case 'r':
-      args->root_dev = arg;
-      break;
-    case 'd':
-      args->dir = arg;
-      break;
-    case 'm':
-      args->dev_map = arg;
-      break;
-    case 'v':
-      verbosity++;
-      break;
-    case 'H':
-      args->hold = arg ? atoi (arg) : -1;
-      break;
-    case ARGP_KEY_END:
-      break;
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
+static struct option options[] =
+  {
+    {"root-device", required_argument, 0, 'r'},
+    {"device-map", required_argument, 0, 'm'},
+    {"directory", required_argument, 0, 'd'},
+    {"hold", required_argument, 0, 'H'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    { 0, 0, 0, 0 }
+  };
+
+static int 
+usage (int status)
+{
+  if (status)
+    fprintf (stderr,
+	     "Try ``grub-emu --help'' for more information.\n");
+  else
+    printf(
+      "Usage: grub-emu [OPTION]...\n"
+      "\n"
+      "GRUB emulator.\n"
+      "\n"
+      "  -r, --root-device=DEV     use DEV as the root device [default=guessed]\n"
+      "  -m, --device-map=FILE     use FILE as the device map [default=%s]\n"
+      "  -d, --directory=DIR       use GRUB files in the directory DIR [default=%s]\n"
+      "  -v, --verbose             print verbose messages\n"
+      "  -H, --hold=SECONDS        wait until a debugger will attach\n"
+      "  -h, --help                display this message and exit\n"
+      "  -V, --version             print version information and exit\n"
+      "\n"
+      "Report bugs to <%s>.\n", DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
+  return status;
 }
-
-static struct argp argp = {options, parse_opt, 0, doc, 0, 0, 0};
 \f
 
 int
 main (int argc, char *argv[])
 {
-  char *dir;
-  
-  struct arguments args =
-    {
-      .dir = DEFAULT_DIRECTORY,
-      .dev_map = DEFAULT_DEVICE_MAP,
-      .hold = 0
-    };
+  char *root_dev = 0;
+  char *dir = DEFAULT_DIRECTORY;
+  char *dev_map = DEFAULT_DEVICE_MAP;
+  volatile int hold = 0;
+  int opt;
   
   progname = "grub-emu";
-  
-  argp_parse (&argp, argc, argv, 0, 0, &args);
+
+  while ((opt = getopt_long(argc, argv, "r:d:m:vH:hV", options, 0)) != -1)
+    switch (opt)
+      {
+      case 'r':
+        root_dev = optarg;
+        break;
+      case 'd':
+        dir = optarg;
+        break;
+      case 'm':
+        dev_map = optarg;
+        break;
+      case 'v':
+        verbosity++;
+        break;
+      case 'H':
+        hold = atoi (optarg);
+        break;
+      case 'h':
+        return usage (0);
+      case 'V':
+        printf("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
+        return 0;
+      default:
+        return usage (1);
+      }
 
   /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */
-  if (args.hold && verbosity > 0)
+  if (hold && verbosity > 0)
     printf ("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n",
             progname, (int) getpid ());
-  while (args.hold)
+  while (hold)
     {
-      if (args.hold > 0)
-        args.hold--;
+      if (hold > 0)
+        hold--;
 
       sleep (1);
     }
   
   /* XXX: This is a bit unportable.  */
-  grub_util_biosdisk_init (args.dev_map);
+  grub_util_biosdisk_init (dev_map);
 
   grub_hostfs_init ();
 
   grub_init_all ();
 
   /* Make sure that there is a root device.  */
-  if (! args.root_dev)
+  if (! root_dev)
     {
-      char *device_name = grub_guess_root_device (args.dir ? : DEFAULT_DIRECTORY);
+      char *device_name = grub_guess_root_device (dir);
       if (! device_name)
-        grub_util_error ("cannot find a device for %s.\n", args.dir ? : DEFAULT_DIRECTORY);
+        grub_util_error ("cannot find a device for %s.\n", dir);
 
-      args.root_dev = grub_util_get_grub_dev (device_name);
-      if (! args.root_dev)
+      root_dev = grub_util_get_grub_dev (device_name);
+      if (! root_dev)
 	{
 	  grub_util_info ("guessing the root device failed, because of `%s'",
 			  grub_errmsg);
@@ -195,9 +200,9 @@ main (int argc, char *argv[])
 	}
     }
 
-  dir = grub_get_prefix (args.dir ? : DEFAULT_DIRECTORY);
-  prefix = xmalloc (strlen (args.root_dev) + strlen (dir) + 1);
-  sprintf (prefix, "%s%s", args.root_dev, dir);
+  dir = grub_get_prefix (dir);
+  prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1);
+  sprintf (prefix, "(%s)%s", root_dev, dir);
   free (dir);
   
   /* Start GRUB!  */
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/util/grub-mkdevicemap.c grub2/util/grub-mkdevicemap.c
--- grub2.orig/util/grub-mkdevicemap.c	2007-08-28 12:18:10.000000000 +0200
+++ grub2/util/grub-mkdevicemap.c	2007-10-11 21:15:24.000000000 +0200
@@ -166,6 +166,9 @@ get_floppy_disk_name (char *name, int un
 #elif defined(__QNXNTO__)
   /* QNX RTP */
   sprintf (name, "/dev/fd%d", unit);
+#elif defined(__CYGWIN__)
+  /* Cygwin */
+  sprintf (name, "/dev/fd%d", unit);
 #else
 # warning "BIOS floppy drives cannot be guessed in your operating system."
   /* Set NAME to a bogus string.  */
@@ -207,6 +210,10 @@ get_ide_disk_name (char *name, int unit)
   /* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could
      contain SCSI disks.  */
   sprintf (name, "/dev/hd%d", unit);
+#elif defined(__CYGWIN__)
+  /* Cygwin */
+  /* Cygwin emulates all disks as SCSI disks /dev/sdX */
+  *name = 0; (void)unit;
 #else
 # warning "BIOS IDE drives cannot be guessed in your operating system."
   /* Set NAME to a bogus string.  */
@@ -248,6 +255,10 @@ get_scsi_disk_name (char *name, int unit
   /* QNX RTP doesn't distinguish SCSI from IDE, so it is better to
      disable the detection of SCSI disks here.  */
   *name = 0;
+#elif defined(__CYGWIN__)
+  /* Cygwin */
+  /* Cygwin emulates all disks as Linux SCSI disks /dev/sdX */
+  sprintf (name, "/dev/sd%c", unit + 'a');
 #else
 # warning "BIOS SCSI drives cannot be guessed in your operating system."
   /* Set NAME to a bogus string.  */
@@ -277,16 +288,16 @@ get_i2o_disk_name (char *name, char unit
 
 /* Check if DEVICE can be read. If an error occurs, return zero,
    otherwise return non-zero.  */
-int
+static int
 check_device (const char *device)
 {
   char buf[512];
   FILE *fp;
 
-  /* If DEVICE is empty, just return 1.  */
+  /* If DEVICE is empty, just return error.  */
   if (*device == 0)
-    return 1;
-  
+    return 0;
+ 
   fp = fopen (device, "r");
   if (! fp)
     {
@@ -513,9 +524,10 @@ make_device_map (const char *device_map,
 	  }
       }
   }
-#endif /* __linux__ */
 
  finish:
+#endif /* __linux__ */
+
   if (fp != stdout)
     fclose (fp);
 }
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/util/grub-probe.c grub2/util/grub-probe.c
--- grub2.orig/util/grub-probe.c	2007-07-22 21:17:26.000000000 +0200
+++ grub2/util/grub-probe.c	2007-10-14 17:28:29.000000000 +0200
@@ -39,12 +39,11 @@
 #define _GNU_SOURCE	1
 #include <getopt.h>
 
-#define PRINT_FS	0
-#define PRINT_DRIVE	1
-#define PRINT_DEVICE	2
-#define PRINT_PARTMAP	3
-
-int print = PRINT_FS;
+#define PRINT_FS	0x01
+#define PRINT_DRIVE	0x02
+#define PRINT_PREFIX	0x04
+#define PRINT_DEVICE	0x08
+#define PRINT_PARTMAP	0x10
 
 void
 grub_putchar (int c)
@@ -70,7 +69,7 @@ grub_refresh (void)
 }
 
 static void
-probe (const char *path)
+probe (const char *path, int types)
 {
   char *device_name;
   char *drive_name = NULL;
@@ -81,20 +80,36 @@ probe (const char *path)
   if (! device_name)
     grub_util_error ("cannot find a device for %s.\n", path);
 
-  if (print == PRINT_DEVICE)
+  if (types & PRINT_DEVICE)
     {
       printf ("%s\n", device_name);
-      goto end;
+      types &= ~PRINT_DEVICE;
+      if (types == 0)
+        goto end;
     }
 
   drive_name = grub_util_get_grub_dev (device_name);
   if (! drive_name)
     grub_util_error ("cannot find a GRUB drive for %s.\n", device_name);
   
-  if (print == PRINT_DRIVE)
+  if (types & PRINT_DRIVE)
     {
       printf ("(%s)\n", drive_name);
-      goto end;
+      types &= ~PRINT_DRIVE;
+      if (types == 0)
+        goto end;
+    }
+
+  if (types & PRINT_PREFIX)
+    {
+      char * prefix = grub_get_prefix (path);
+      if (! prefix)
+        grub_util_error ("cannot find prefix for %s.\n", path);
+      printf ("%s\n", prefix);
+      free (prefix);
+      types &= ~PRINT_PREFIX;
+      if (types == 0)
+        goto end;
     }
 
   grub_util_info ("opening %s", drive_name);
@@ -102,7 +117,7 @@ probe (const char *path)
   if (! dev)
     grub_util_error ("%s", grub_errmsg);
 
-  if (print == PRINT_PARTMAP)
+  if (types & PRINT_PARTMAP)
     {
       if (dev->disk->partition == NULL)
         grub_util_error ("Cannot detect partition map for %s", drive_name);
@@ -119,14 +134,16 @@ probe (const char *path)
         printf ("sun\n");
       else
         grub_util_error ("Unknown partition map %s", dev->disk->partition->partmap->name);
-      goto end;
     }
 
-  fs = grub_fs_probe (dev);
-  if (! fs)
-    grub_util_error ("%s", grub_errmsg);
+  if (types & PRINT_FS)
+    {
+      fs = grub_fs_probe (dev);
+      if (! fs)
+        grub_util_error ("%s", grub_errmsg);
 
-  printf ("%s\n", fs->name);
+      printf ("%s\n", fs->name);
+    }
   
   grub_device_close (dev);
 
@@ -159,8 +176,9 @@ Usage: grub-probe [OPTION]... PATH\n\
 Probe device information for a given path.\n\
 \n\
   -m, --device-map=FILE     use FILE as the device map [default=%s]\n\
-  -t, --target=(fs|drive|device|partmap)\n\
-                            print filesystem module, GRUB drive, system device or partition map module [default=fs]\n\
+  -t, --target=(fs|drive|prefix|device|partmap|all)\n\
+                            print filesystem module, GRUB drive, path prefix, system device\n\
+                            or partition map module [default=fs]\n\
   -h, --help                display this message and exit\n\
   -V, --version             print version information and exit\n\
   -v, --verbose             print verbose messages\n\
@@ -175,6 +193,7 @@ Report bugs to <%s>.\n\
 int
 main (int argc, char *argv[])
 {
+  unsigned types = 0;
   char *dev_map = 0;
   char *path;
   
@@ -199,13 +218,17 @@ main (int argc, char *argv[])
 
 	  case 't':
 	    if (!strcmp (optarg, "fs"))
-	      print = PRINT_FS;
+	      types |= PRINT_FS;
 	    else if (!strcmp (optarg, "drive"))
-	      print = PRINT_DRIVE;
+	      types |= PRINT_DRIVE;
+	    else if (!strcmp (optarg, "prefix"))
+	      types |= PRINT_PREFIX;
 	    else if (!strcmp (optarg, "device"))
-	      print = PRINT_DEVICE;
+	      types |= PRINT_DEVICE;
 	    else if (!strcmp (optarg, "partmap"))
-	      print = PRINT_PARTMAP;
+	      types |= PRINT_PARTMAP;
+	    else if (!strcmp (optarg, "all"))
+	      types = ~0;
 	    else
 	      usage (1);
 	    break;
@@ -227,6 +250,8 @@ main (int argc, char *argv[])
 	    break;
 	  }
     }
+  if (types == 0)
+    types = PRINT_FS;
 
   /* Obtain PATH.  */
   if (optind >= argc)
@@ -250,7 +275,7 @@ main (int argc, char *argv[])
   grub_init_all ();
 
   /* Do it.  */
-  probe (path);
+  probe (path, types);
   
   /* Free resources.  */
   grub_fini_all ();
diff -rupN -x CVS -x configure -x autom4te.cache -x '*.mk' -x '.*' -x '*~' grub2.orig/util/hostfs.c grub2/util/hostfs.c
--- grub2.orig/util/hostfs.c	2007-08-02 19:24:06.000000000 +0200
+++ grub2/util/hostfs.c	2007-10-13 17:17:20.000000000 +0200
@@ -25,6 +25,29 @@
 #include <dirent.h>
 #include <stdio.h>
 
+
+#ifndef DT_DIR
+/* dirent.d_type is a BSD extension, not part of POSIX */
+#include <sys/stat.h>
+#include <string.h>
+
+static int
+is_dir(const char *path, const char *name)
+{
+  int len1 = strlen(path), len2 = strlen(name);
+  char pathname[len1+1+len2+1+13];
+  struct stat st;
+  strcpy (pathname, path);
+  /* Avoid UNC-path "//name" on Cygwin */
+  if (len1 > 0 && pathname[len1-1] != '/')
+    strcat (pathname, "/");
+  strcat (pathname, name);
+  if (stat (pathname, &st))
+    return 0;
+  return S_ISDIR(st.st_mode);
+}
+#endif
+
 static grub_err_t
 grub_hostfs_dir (grub_device_t device, const char *path, 
 		 int (*hook) (const char *filename, int dir))
@@ -48,7 +71,11 @@ grub_hostfs_dir (grub_device_t device, c
       if (! de)
 	break;
 
+#ifdef DT_DIR
       hook (de->d_name, de->d_type == DT_DIR);
+#else
+      hook (de->d_name, is_dir(path, de->d_name));
+#endif
     }
 
   closedir (dir);
@@ -101,6 +128,7 @@ static grub_err_t
 grub_hostfs_label (grub_device_t device __attribute ((unused)),
 		   char **label __attribute ((unused)))
 {
+  *label = 0;
   return GRUB_ERR_NONE;
 }
 

  reply	other threads:[~2007-10-21 13:07 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-16 12:03 [PATCH] grub2 for Cygwin Christian Franke
2007-10-16 13:34 ` Robert Millan
2007-10-20 23:37 ` Robert Millan
2007-10-21 13:07   ` Christian Franke [this message]
2007-10-21 13:18     ` Vesa Jääskeläinen
2007-10-21 13:51       ` Christian Franke
2007-10-21 14:13         ` Robert Millan
2007-11-09 13:57         ` Marco Gerards
2007-11-09 15:07           ` Christian Franke
2008-04-02 22:07 ` Christian Franke
2008-04-03  8:03   ` Bean
  -- strict thread matches above, loose matches on Subject: below --
2008-04-03 13:28 Christian Franke
2008-04-03 16:02 ` Bean
2008-04-03 19:56   ` Christian Franke
2008-04-03 20:38     ` Pavel Roskin
2008-04-05 12:44       ` Christian Franke
2008-04-07  2:07         ` Pavel Roskin
2008-04-07 19:46           ` Christian Franke
2008-04-13 10:37             ` Robert Millan
2008-04-13 10:39 ` Robert Millan
2008-04-13 20:24   ` Christian Franke
2008-04-14 12:00     ` Robert Millan
2008-04-14 13:36       ` Christian Franke
2008-04-15 13:12         ` Robert Millan
2008-04-15 14:26           ` Christian Franke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=471B4EFB.6020009@t-online.de \
    --to=christian.franke@t-online.de \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.