grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] grub2 for Cygwin


From: Christian Franke
Subject: Re: [PATCH] grub2 for Cygwin
Date: Sun, 21 Oct 2007 15:07:07 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070802 SeaMonkey/1.1.4

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

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 <address@hidden>:
+
+       * 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 @@
 address@hidden@
 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}
 
 address@hidden: #{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 
address@hidden $^
+       $(TARGET_MOD_COPY) address@hidden $@ || (rm -f address@hidden; exit 1)
+       rm -f address@hidden
+       $(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 += address@hidden #{objs_str}
+    "CLEANFILES += address@hidden(EXEEXT) #{objs_str}
 MOSTLYCLEANFILES += #{deps_str}
 
 address@hidden: $(#{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)
 }
 
 
-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};
 
 
 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 via email to

[Prev in Thread] Current Thread [Next in Thread]