From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1IjaWf-0003T9-5n for mharc-grub-devel@gnu.org; Sun, 21 Oct 2007 09:07:29 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IjaWd-0003T3-1i for grub-devel@gnu.org; Sun, 21 Oct 2007 09:07:27 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IjaWb-0003Sr-OI for grub-devel@gnu.org; Sun, 21 Oct 2007 09:07:26 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IjaWb-0003So-Hg for grub-devel@gnu.org; Sun, 21 Oct 2007 09:07:25 -0400 Received: from mailout06.sul.t-online.de ([194.25.134.19] helo=mailout06.sul.t-online.com) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1IjaWa-0003FW-9b for grub-devel@gnu.org; Sun, 21 Oct 2007 09:07:25 -0400 Received: from fwd32.aul.t-online.de by mailout06.sul.t-online.com with smtp id 1IjaWW-0007C3-00; Sun, 21 Oct 2007 15:07:20 +0200 Received: from [10.3.2.2] (XZGrRkZJQh7l4iy+y-IxwdTha6Nq2xl-NW3GlyeFY2JNrV75TCrvcsDmO2+QJRRg9y@[217.235.215.176]) by fwd32.aul.t-online.de with esmtp id 1IjaWI-217nm40; Sun, 21 Oct 2007 15:07:06 +0200 Message-ID: <471B4EFB.6020009@t-online.de> Date: Sun, 21 Oct 2007 15:07:07 +0200 From: Christian Franke User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070802 SeaMonkey/1.1.4 MIME-Version: 1.0 To: The development of GRUB 2 References: <1Ihl95-0ez6x60@fwd32.aul.t-online.de> <20071020233721.GA9939@thorin> In-Reply-To: <20071020233721.GA9939@thorin> Content-Type: multipart/mixed; boundary="------------010405030207040000090108" X-ID: XZGrRkZJQh7l4iy+y-IxwdTha6Nq2xl-NW3GlyeFY2JNrV75TCrvcsDmO2+QJRRg9y X-TOI-MSGID: 62a9a5aa-bd4a-4073-9d0b-9e68d1630cfa X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 3) Subject: Re: [PATCH] grub2 for Cygwin X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Oct 2007 13:07:27 -0000 This is a multi-part message in MIME format. --------------010405030207040000090108 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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 --------------010405030207040000090108 Content-Type: text/x-patch; name="grub2-20071016-cygwin.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="grub2-20071016-cygwin.patch" 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 : + + * 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 /* ioctl */ +# include /* 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 #include #include +#ifdef __CYGWIN__ +#include +#include +#endif #include #include @@ -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 #include -#include +#include #include #include #include @@ -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 -#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 #include + +#ifndef DT_DIR +/* dirent.d_type is a BSD extension, not part of POSIX */ +#include +#include + +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; } --------------010405030207040000090108--