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;
}
next prev parent 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.