2008-01-28 Tristan Gingold
* geninit.sh: Call _init with a null argument.
* configure.ac: Add ia64-efi target.
* Makefile.in (STRIP_FLAGS): Declare (overriden on ia64).
(RMKFILES): Use a wildcard.
* genmk.rb: Use STRIP_FLAGS for strip.
* util/ia64/efi/grub-install.in: New file.
* util/ia64/efi/pe32.h: New file.
* util/ia64/efi/elf2pe.c: New file.
* normal/ia64/setjmp.S: New file (from glibc).
* normal/ia64/longjmp.S: New file (from glibc).
* loader/ia64/efi/linux_normal.c: New file.
* loader/ia64/efi/linux.c: New file.
* conf/ia64-efi.rmk: New file.
* commands/efi/systab.c: New file.
* commands/efi/memmap.c: New file.
* commands/efi/acpi.c: New file.
* fs/fat.c (grub_fat_find_dir): Use case insensitive string
compare as filenames are not case sensitive.
* include/grub/efi/efi.h: Declare grub_efi_allocate_boot_pages and
grub_efi_free_boot_pages.
* include/grub/misc.h: Declare grub_strcasecmp.
* include/grub/kernel.h: Export grub_machine_fini.
* include/grub/dl.h: Use attribute instead of raw asm statement.
Use grub_module as prefix to make identification easier.
* include/grub/ia64/efi/time.h: New file.
* include/grub/ia64/efi/misc.h: New file.
* include/grub/ia64/efi/loader.h: New file.
* include/grub/ia64/efi/kernel.h: New file.
* include/grub/ia64/time.h: New file.
* include/grub/ia64/setjmp.h: New file.
* include/grub/ia64/types.h: New file.
* kern/efi/mm.c (BYTES_TO_PAGES): Round instead of truncating.
(grub_efi_allocate_boot_pages): Low level interface to allocate_pages.
(grub_efi_free_boot_pages): Low level interface to free_pages.
(grub_efi_allocate_pages): Call grub_efi_allocate_boot_pages.
(grub_efi_free_pages): Call grubèefi_free_boot_pages.
(add_memory_regions): Add debug message in ifdef.
(add_memory_regions): Add debug message in ifdef.
(grub_efi_mm_init): Do not constraint memory map length, add space for
a few more entries.
* kern/misc.c (grub_strcasecmp): New function.
* kern/dl.c (grub_init_module): New function. Register an already
linked module.
* kern/ia64/efi/elf_ia64_efi.lds: New file.
* kern/ia64/efi/startup.S: New file.
* kern/ia64/efi/init.c: New file.
* kern/ia64/trampoline.S: New file.
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/Makefile.in grub2/Makefile.in
--- grub2.orig/Makefile.in 2008-01-08 11:00:42.000000000 +0100
+++ grub2/Makefile.in 2008-01-29 06:21:37.000000000 +0100
@@ -67,6 +67,7 @@ TARGET_CFLAGS = @TARGET_CFLAGS@
TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I. -Iinclude -I$(srcdir)/include \
-Wall -W
TARGET_LDFLAGS = @TARGET_LDFLAGS@
+STRIP_FLAGS=--strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment
OBJCOPY = @OBJCOPY@
STRIP = @STRIP@
NM = @NM@
@@ -82,8 +83,7 @@ enable_grub_emu = @enable_grub_emu@
### General variables.
-RMKFILES = $(addprefix conf/,common.rmk i386-pc.rmk powerpc-ieee1275.rmk \
- sparc64-ieee1275.rmk i386-efi.rmk)
+RMKFILES = $(wildcard $(srcdir)/conf/*.rmk)
MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES))
PKGLIB = $(pkglib_IMAGES) $(pkglib_MODULES) $(pkglib_PROGRAMS) \
@@ -97,13 +97,13 @@ MOSTLYCLEANFILES =
DISTCLEANFILES = config.status config.cache config.log config.h \
Makefile stamp-h include/grub/cpu include/grub/machine \
gensymlist.sh genkernsyms.sh
-MAINTAINER_CLEANFILES = $(srcdir)/configure $(addprefix $(srcdir)/,$(MKFILES))
+MAINTAINER_CLEANFILES = $(srcdir)/configure $(MKFILES)
# The default target.
all: all-local
### Include an arch-specific Makefile.
-$(addprefix $(srcdir)/,$(MKFILES)): %.mk: %.rmk genmk.rb
+$(MKFILES): %.mk: %.rmk genmk.rb
if test "x$(RUBY)" = x; then \
touch $@; \
else \
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/commands/efi/acpi.c grub2/commands/efi/acpi.c
--- grub2.orig/commands/efi/acpi.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2/commands/efi/acpi.c 2008-01-29 06:27:02.000000000 +0100
@@ -0,0 +1,190 @@
+/* acpi.c - Display acpi tables. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+#include
+#include
+#include
+#include
+
+static grub_uint32_t read16 (grub_uint8_t *p)
+{
+ return grub_le_to_cpu16 (*(grub_uint16_t *)p);
+}
+
+static grub_uint32_t read32 (grub_uint8_t *p)
+{
+ return grub_le_to_cpu32 (*(grub_uint32_t *)p);
+}
+
+static grub_uint64_t read64 (grub_uint8_t *p)
+{
+ return grub_le_to_cpu64 (*(grub_uint64_t *)p);
+}
+
+static void
+disp_acpi_table (grub_uint8_t *t)
+{
+ int i;
+ grub_printf ("%c%c%c%c %4dB rev=%d OEM=", t[0], t[1], t[2], t[3],
+ read32 (t + 4), t[8]);
+ for (i = 0; i < 6; i++)
+ grub_printf ("%c", t[10 + i]);
+ grub_printf (" ");
+ for (i = 0; i < 8; i++)
+ grub_printf ("%c", t[16 + i]);
+ grub_printf (" V=%08lx ", read32 (t + 24));
+ for (i = 0; i < 4; i++)
+ grub_printf ("%c", t[28 + i]);
+ grub_printf (" %08lx\n", read32 (t + 32));
+
+}
+
+static void
+disp_acpi_apic_table (grub_uint8_t *t)
+{
+ grub_uint8_t *d;
+ grub_uint32_t len;
+ grub_uint32_t flags;
+
+ disp_acpi_table (t);
+ grub_printf ("Local APIC=%08lx Flags=%08lx\n",
+ read32 (t + 36), read32 (t + 40));
+ len = read32 (t + 4);
+ len -= 44;
+ d = t + 44;
+ while (len > 0)
+ {
+ grub_uint32_t l = d[1];
+ grub_printf (" type=%x l=%d ", d[0], l);
+
+ switch (d[0])
+ {
+ case 2:
+ grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x",
+ d[2], d[3], read32 (d + 4), read16 (d + 8));
+ break;
+ case 6:
+ grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016llx",
+ d[2], read32 (d + 4), read64 (d + 8));
+ break;
+ case 7:
+ flags = read32 (d + 8);
+ grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
+ d[2], d[3], d[4], flags);
+ if (flags & 1)
+ grub_printf (" Enabled");
+ else
+ grub_printf (" Disabled");
+ if (l >= 17)
+ grub_printf ("\n"
+ " UID val=%08x, Str=%s", read32 (d + 12), d + 16);
+ break;
+ case 8:
+ grub_printf ("Platform INT flags=%04x type=%02x (",
+ read16 (d + 2), d[4]);
+ if (d[4] <= 3)
+ {
+ static const char * const platint_type[4] =
+ {"Nul", "PMI", "INIT", "CPEI"};
+ grub_printf ("%s", platint_type[d[4]]);
+ }
+ else
+ grub_printf ("??");
+ grub_printf (") ID=%02x EID=%02x\n", d[5], d[6]);
+ grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x",
+ d[7], read32 (d + 8), read32 (d + 12));
+ break;
+ default:
+ grub_printf (" ??");
+ }
+ grub_printf ("\n");
+ d += l;
+ len -= l;
+ }
+}
+
+static void
+disp_acpi_xsdt_table (grub_uint8_t *t)
+{
+ grub_uint32_t len;
+ grub_uint8_t *desc;
+
+ disp_acpi_table (t);
+ len = read32 (t + 4) - 36;
+ desc = t + 36;
+ while (len > 0)
+ {
+ t = read64 (desc);
+
+ if (t[0] == 'A' && t[1] == 'P' && t[2] == 'I' && t[3] == 'C')
+ disp_acpi_apic_table (t);
+ else
+ disp_acpi_table (t);
+ desc += 8;
+ len -= 8;
+ }
+}
+
+static void
+disp_acpi_rsdt_table (grub_uint8_t *t)
+{
+ grub_uint32_t len;
+ grub_uint8_t *desc;
+
+ disp_acpi_table (t);
+ len = read32 (t + 4) - 36;
+ desc = t + 36;
+ while (len > 0)
+ {
+ t = read32 (desc);
+
+ if (t != NULL)
+ disp_acpi_table (t);
+ desc += 4;
+ len -= 4;
+ }
+}
+
+void
+disp_acpi_rsdp_table (grub_uint8_t *rsdp)
+{
+ grub_uint8_t *t = rsdp;
+ int i;
+ grub_uint8_t *xsdt;
+
+ grub_printf ("RSDP signature:");
+ for (i = 0; i < 8; i++)
+ grub_printf ("%c", t[i]);
+ grub_printf (" chksum:%02x, OEM-ID: ", t[8]);
+ for (i = 0; i < 6; i++)
+ grub_printf ("%c", t[9 + i]);
+ grub_printf (" rev=%d\n", t[15]);
+ grub_printf ("RSDT=%08lx", read32 (t + 16));
+ if (t[15] == 2)
+ {
+ xsdt = read64 (t + 24);
+ grub_printf (" len=%d XSDT=%016llx\n", read32 (t + 20), xsdt);
+ grub_printf ("\n");
+ disp_acpi_xsdt_table (xsdt);
+ }
+ else
+ {
+ grub_printf ("\n");
+ disp_acpi_rsdt_table (read32 (t + 16));
+ }
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/commands/efi/memmap.c grub2/commands/efi/memmap.c
--- grub2.orig/commands/efi/memmap.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2/commands/efi/memmap.c 2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,143 @@
+/* memmap.c - Display memory map. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define ADD_MEMORY_DESCRIPTOR(desc, size) \
+ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+static grub_err_t
+grub_cmd_memmap (struct grub_arg_list *state, int argc, char **args)
+{
+ grub_efi_uintn_t map_size;
+ grub_efi_memory_descriptor_t *memory_map;
+ grub_efi_memory_descriptor_t *memory_map_end;
+ grub_efi_memory_descriptor_t *desc;
+ grub_efi_uintn_t desc_size;
+
+ map_size = 0;
+ if (grub_efi_get_memory_map (&map_size, NULL, NULL, &desc_size, 0) < 0)
+ return 0;
+
+ memory_map = grub_malloc (map_size);
+ if (memory_map == NULL)
+ return 0;
+ if (grub_efi_get_memory_map (&map_size, memory_map, NULL, &desc_size, 0) < 0)
+ goto fail;
+
+ grub_set_more (1);
+
+ grub_printf
+ ("Type Physical start - end #Pages "
+ " Size Attributes\n");
+ memory_map_end = ADD_MEMORY_DESCRIPTOR(memory_map, map_size);
+ for (desc = memory_map;
+ desc < memory_map_end;
+ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
+ {
+ grub_efi_uintn_t size;
+ grub_efi_uint64_t attr;
+ static const char types_str[][9] =
+ {
+ "reserved",
+ "ldr-code",
+ "ldr-data",
+ "BS-code ",
+ "BS-data ",
+ "RT-code ",
+ "RT-data ",
+ "conv-mem",
+ "unusable",
+ "ACPI-rec",
+ "ACPI-nvs",
+ "MMIO ",
+ "IO-ports",
+ "PAL-code"
+ };
+ if (desc->type < sizeof (types_str) / sizeof (types_str[0]))
+ grub_printf ("%s ", types_str[desc->type]);
+ else
+ grub_printf ("Unk %02x ", desc->type);
+
+ grub_printf (" %016llx-%016llx %08lx",
+ desc->physical_start,
+ desc->physical_start + (desc->num_pages << 12) - 1,
+ desc->num_pages);
+
+ size = desc->num_pages << (12 - 10);
+ if (size < 1024)
+ grub_printf (" %4uKB", size);
+ else
+ {
+ size /= 1024;
+ if (size < 1024)
+ grub_printf (" %4uMB", size);
+ else
+ {
+ size /= 1024;
+ grub_printf (" %4uGB", size);
+ }
+ }
+
+ attr = desc->attribute;
+ if (attr & GRUB_EFI_MEMORY_RUNTIME)
+ grub_printf (" RT");
+ if (attr & GRUB_EFI_MEMORY_UC)
+ grub_printf (" UC");
+ if (attr & GRUB_EFI_MEMORY_WC)
+ grub_printf (" WC");
+ if (attr & GRUB_EFI_MEMORY_WT)
+ grub_printf (" WT");
+ if (attr & GRUB_EFI_MEMORY_WB)
+ grub_printf (" WB");
+ if (attr & GRUB_EFI_MEMORY_UCE)
+ grub_printf (" UCE");
+ if (attr & GRUB_EFI_MEMORY_WP)
+ grub_printf (" WP");
+ if (attr & GRUB_EFI_MEMORY_RP)
+ grub_printf (" RP");
+ if (attr & GRUB_EFI_MEMORY_XP)
+ grub_printf (" XP");
+
+ grub_printf ("\n");
+ }
+
+ grub_set_more (0);
+
+ fail:
+ grub_free (memory_map);
+ return 0;
+}
+
+GRUB_MOD_INIT(memmap)
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("memmap", grub_cmd_memmap, GRUB_COMMAND_FLAG_BOTH,
+ "memmap",
+ "Display memory map.", NULL);
+}
+
+GRUB_MOD_FINI(memmap)
+{
+ grub_unregister_command ("memmap");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/commands/efi/systab.c grub2/commands/efi/systab.c
--- grub2.orig/commands/efi/systab.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2/commands/efi/systab.c 2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,258 @@
+/* systab.c - Display EFI systab. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define ACPI_20_TABLE_GUID \
+{0x8868e871,0xe4f1,0x11d3,{0xbc,0x22,0x0,0x80,0xc7,0x3c,0x88,0x81}}
+#define ACPI_TABLE_GUID \
+{0xeb9d2d30,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define SAL_SYSTEM_TABLE_GUID \
+{0xeb9d2d32,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define SMBIOS_TABLE_GUID \
+{0xeb9d2d31,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define MPS_TABLE_GUID \
+{0xeb9d2d2f,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define HCDP_TABLE_GUID \
+{0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
+
+struct guid_mapping
+{
+ grub_efi_guid_t guid;
+ const char *name;
+ void (*disp)(struct guid_mapping *map, void *table);
+};
+
+static void disp_sal (struct guid_mapping *map, void *table);
+static void disp_acpi (struct guid_mapping *map, void *table);
+
+static const struct guid_mapping guid_mappings[] =
+ {
+ { ACPI_20_TABLE_GUID, "ACPI-2.0", disp_acpi},
+ { ACPI_TABLE_GUID, "ACPI-1.0", disp_acpi},
+ { SAL_SYSTEM_TABLE_GUID, "SAL", disp_sal},
+ { SMBIOS_TABLE_GUID, "SMBIOS",NULL},
+ { MPS_TABLE_GUID, "MPS", NULL},
+ { HCDP_TABLE_GUID, "HCDP", NULL}
+ };
+
+struct sal_system_table
+{
+ grub_uint32_t signature;
+ grub_uint32_t total_table_len;
+ grub_uint16_t sal_rev;
+ grub_uint16_t entry_count;
+ grub_uint8_t checksum;
+ grub_uint8_t reserved1[7];
+ grub_uint16_t sal_a_version;
+ grub_uint16_t sal_b_version;
+ grub_uint8_t oem_id[32];
+ grub_uint8_t product_id[32];
+ grub_uint8_t reserved2[8];
+};
+
+static void
+disp_sal (struct guid_mapping *map, void *table)
+{
+ struct sal_system_table *t = table;
+ grub_uint8_t *desc = table;
+ grub_uint32_t len, l;
+
+ grub_printf ("SAL rev: %02x, signature: %x, len:%x\n",
+ t->sal_rev, t->signature, t->total_table_len);
+ grub_printf ("nbr entry: %d, chksum: %02x, SAL version A: %02x B: %02x\n",
+ t->entry_count, t->checksum,
+ t->sal_a_version, t->sal_b_version);
+ grub_printf ("OEM-ID: %-32s\n", t->oem_id);
+ grub_printf ("Product-ID: %-32s\n", t->product_id);
+
+ desc += sizeof (struct sal_system_table);
+ len = t->total_table_len - sizeof (struct sal_system_table);
+ while (len > 0)
+ {
+ switch (*desc)
+ {
+ case 0:
+ l = 48;
+ grub_printf (" Entry point: PAL=%016lx SAL=%016lx GP=%016lx\n",
+ *(grub_uint64_t*)(desc + 8),
+ *(grub_uint64_t*)(desc + 16),
+ *(grub_uint64_t*)(desc + 24));
+ break;
+ case 1:
+ l = 32;
+ grub_printf (" Memory descriptor entry addr=%016llx len=%uKB\n",
+ *(grub_uint64_t*)(desc + 8),
+ *(grub_uint32_t*)(desc + 16) * 4);
+ grub_printf (" sal_used=%d attr=%x AR=%x attr_mask=%x "
+ "type=%x usage=%x\n",
+ desc[1], desc[2], desc[3], desc[4], desc[5], desc[6]);
+ break;
+ case 2:
+ l = 16;
+ grub_printf (" Platform features: %02x", desc[1]);
+ if (desc[1] & 0x01)
+ grub_printf (" BusLock");
+ if (desc[1] & 0x02)
+ grub_printf (" IrqRedirect");
+ if (desc[1] & 0x04)
+ grub_printf (" IPIRedirect");
+ grub_printf ("\n");
+ break;
+ case 3:
+ l = 32;
+ grub_printf (" TR type=%d num=%d va=%016llx pte=%016llx\n",
+ desc[1], desc[2],
+ *(grub_uint64_t *)(desc + 8),
+ *(grub_uint64_t *)(desc + 16));
+ break;
+ case 4:
+ l = 16;
+ grub_printf (" PTC coherence nbr=%d addr=%016llx\n",
+ desc[1], *(grub_uint64_t *)(desc + 8));
+ break;
+ case 5:
+ l = 16;
+ grub_printf (" AP wake-up: mec=%d vect=%x\n",
+ desc[1], *(grub_uint64_t *)(desc + 8));
+ break;
+ default:
+ grub_printf (" unknown entry %d\n", *desc);
+ return;
+ }
+ desc += l;
+ len -= l;
+ }
+}
+
+static void
+disp_acpi (struct guid_mapping *map, void *table)
+{
+ disp_acpi_rsdp_table (table);
+}
+
+static void
+disp_systab (void)
+{
+ grub_efi_char16_t *vendor;
+ const grub_efi_system_table_t *st = grub_efi_system_table;
+ grub_efi_configuration_table_t *t;
+ unsigned int i;
+
+ grub_printf ("Signature: %016llx revision: %08x\n",
+ st->hdr.signature, st->hdr.revision);
+ grub_printf ("Vendor: ");
+ for (vendor = st->firmware_vendor; *vendor; vendor++)
+ grub_printf ("%c", *vendor);
+ grub_printf (", Version=%x\n", st->firmware_revision);
+
+ grub_printf ("%ld tables:\n", st->num_table_entries);
+ t = st->configuration_table;
+ for (i = 0; i < st->num_table_entries; i++)
+ {
+ unsigned int j;
+
+ grub_printf ("%016llx ", (grub_uint64_t)t->vendor_table);
+
+ grub_printf ("%08x-%04x-%04x-",
+ t->vendor_guid.data1, t->vendor_guid.data2,
+ t->vendor_guid.data3);
+ for (j = 0; j < 8; j++)
+ grub_printf ("%02x", t->vendor_guid.data4[j]);
+
+ for (j = 0; j < sizeof (guid_mappings)/sizeof(guid_mappings[0]); j++)
+ if (grub_memcmp (&guid_mappings[j].guid, &t->vendor_guid,
+ sizeof (grub_efi_guid_t)) == 0)
+ grub_printf (" %s", guid_mappings[j].name);
+
+ grub_printf ("\n");
+ t++;
+ }
+}
+
+static void
+disp_systab_entry (const char *name)
+{
+ const grub_efi_system_table_t *st = grub_efi_system_table;
+ grub_efi_configuration_table_t *t;
+ unsigned int i;
+ struct guid_mapping *map;
+
+ map = NULL;
+ for (i = 0; i < sizeof (guid_mappings)/sizeof(guid_mappings[0]); i++)
+ if (grub_strcmp (guid_mappings[i].name, name) == 0)
+ {
+ map = &guid_mappings[i];
+ break;
+ }
+ if (map == NULL)
+ {
+ grub_printf ("System table '%s' unknown\n", name);
+ return;
+ }
+ if (map->disp == NULL)
+ {
+ grub_printf ("Don't know how to display table '%s'\n", name);
+ return;
+ }
+ t = st->configuration_table;
+ for (i = 0; i < st->num_table_entries; i++)
+ {
+ if (grub_memcmp (&map->guid, &t->vendor_guid,
+ sizeof (grub_efi_guid_t)) == 0)
+ {
+ grub_set_more (1);
+ (*map->disp)(map, t->vendor_table);
+ grub_set_more (0);
+ return;
+ }
+ t++;
+ }
+ grub_printf ("Systab '%s' not found\n", map->name);
+}
+
+static grub_err_t
+grub_cmd_systab (struct grub_arg_list *state, int argc, char **args)
+{
+ int i;
+
+ if (argc == 0)
+ disp_systab ();
+ else
+ for (i = 0; i < argc; i++)
+ disp_systab_entry (args[i]);
+ return 0;
+}
+
+GRUB_MOD_INIT(systab)
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("systab", grub_cmd_systab, GRUB_COMMAND_FLAG_BOTH,
+ "systab [NAME]",
+ "Display EFI system table.", NULL);
+}
+
+GRUB_MOD_FINI(systab)
+{
+ grub_unregister_command ("systab");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/conf/ia64-efi.rmk grub2/conf/ia64-efi.rmk
--- grub2.orig/conf/ia64-efi.rmk 1970-01-01 01:00:00.000000000 +0100
+++ grub2/conf/ia64-efi.rmk 2008-01-29 06:39:34.000000000 +0100
@@ -0,0 +1,127 @@
+# -*- makefile -*-
+
+COMMON_ASFLAGS = -nostdinc -fno-builtin
+COMMON_CFLAGS = -fno-builtin -fpic -minline-int-divide-max-throughput
+COMMON_LDFLAGS = -melf_64 -nostdlib
+
+STRIP_FLAGS=-R .note -R .comment -X
+
+# Utilities.
+bin_UTILITIES = grub-elf2pe
+#sbin_UTILITIES = grub-emu
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/ia64/efi/grub-install.in
+
+pkgdata_DATA += kern/ia64/efi/elf_ia64_efi.lds
+
+# For grub-elf2pe
+grub_elf2pe_SOURCES = util/ia64/efi/elf2pe.c
+grub_elf2pe_CFLAGS = -DELF2PE_IA64
+
+# For grub-emu.
+grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
+ commands/configfile.c commands/help.c \
+ commands/terminal.c commands/ls.c commands/test.c \
+ commands/search.c commands/blocklist.c \
+ disk/loopback.c \
+ \
+ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
+ fs/hfsplus.c fs/iso9660.c fs/jfs.c fs/minix.c \
+ fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
+ fs/ufs.c fs/xfs.c \
+ \
+ io/gzio.c \
+ kern/device.c kern/disk.c kern/dl.c kern/env.c kern/err.c \
+ normal/execute.c kern/file.c kern/fs.c normal/lexer.c \
+ kern/loader.c kern/main.c kern/misc.c kern/parser.c \
+ grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \
+ normal/arg.c normal/cmdline.c normal/command.c normal/function.c\
+ normal/completion.c normal/main.c \
+ normal/menu.c normal/menu_entry.c normal/misc.c normal/script.c \
+ partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \
+ partmap/acorn.c partmap/gpt.c \
+ util/console.c util/grub-emu.c util/misc.c \
+ util/i386/pc/misc.c grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Modules.
+pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod \
+ _linux.mod linux.mod memmap.mod systab.mod
+
+# For kernel.mod.
+kernel_mod_EXPORTS = no
+kernel_mod_SOURCES = kern/ia64/efi/startup.S \
+ kern/ia64/trampoline.S \
+ kern/main.c kern/device.c \
+ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+ kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
+ kern/i386/dl.c kern/ia64/efi/init.c kern/parser.c kern/partition.c \
+ kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
+ term/efi/console.c disk/efi/efidisk.c
+kernel_mod_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
+ file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h partition.h \
+ pc_partition.h rescue.h symbol.h term.h types.h cache.h \
+ i386/efi/time.h efi/efi.h efi/time.h efi/disk.h ia64/efi/misc.h
+kernel_mod_CFLAGS = $(COMMON_CFLAGS)
+kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+MOSTLYCLEANFILES += symlist.c
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh
+ /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh
+ /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# For normal.mod.
+normal_mod_DEPENDENCIES = grub_script.tab.c grub_script.tab.h
+normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \
+ normal/completion.c normal/execute.c \
+ normal/function.c normal/lexer.c normal/main.c normal/menu.c \
+ normal/menu_entry.c normal/misc.c grub_script.tab.c \
+ normal/script.c \
+ normal/ia64/setjmp.S normal/ia64/longjmp.S normal/color.c
+
+normal_mod_CFLAGS = $(COMMON_CFLAGS)
+normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
+normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For _chain.mod.
+_chain_mod_SOURCES = loader/efi/chainloader.c
+_chain_mod_CFLAGS = $(COMMON_CFLAGS)
+_chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/efi/chainloader_normal.c
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For _linux.mod.
+_linux_mod_SOURCES = loader/ia64/efi/linux.c
+_linux_mod_CFLAGS = $(COMMON_CFLAGS)
+_linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/ia64/efi/linux_normal.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memmap.mod.
+memmap_mod_SOURCES = commands/efi/memmap.c
+memmap_mod_CFLAGS = $(COMMON_CFLAGS)
+memmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For systab.mod.
+systab_mod_SOURCES = commands/efi/systab.c commands/efi/acpi.c
+systab_mod_CFLAGS = $(COMMON_CFLAGS)
+systab_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/common.mk
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/config.h.in grub2/config.h.in
--- grub2.orig/config.h.in 2008-01-15 21:05:44.000000000 +0100
+++ grub2/config.h.in 2008-01-29 06:38:00.000000000 +0100
@@ -88,10 +88,10 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
-/* The size of `long', as computed by sizeof. */
+/* The size of a `long', as computed by sizeof. */
#undef SIZEOF_LONG
-/* The size of `void *', as computed by sizeof. */
+/* The size of a `void *', as computed by sizeof. */
#undef SIZEOF_VOID_P
/* Define it to either start or _start */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/configure.ac grub2/configure.ac
--- grub2.orig/configure.ac 2008-01-15 21:05:44.000000000 +0100
+++ grub2/configure.ac 2008-01-28 16:29:57.000000000 +0100
@@ -53,7 +53,8 @@ case "$target_cpu" in
powerpc) ;;
powerpc64) target_cpu=powerpc target_m32=1;;
sparc64) ;;
- *) AC_MSG_ERROR([unsupported CPU type]) ;;
+ ia64) ;;
+ *) AC_MSG_ERROR([unsupported CPU type $target_cpu]) ;;
esac
# Specify the platform (such as firmware).
@@ -68,6 +69,7 @@ if test "x$with_platform" = x; then
i386-*) platform=pc ;;
powerpc-*) platform=ieee1275 ;;
sparc64-*) platform=ieee1275 ;;
+ ia64*) platform=efi ;;
*) AC_MSG_ERROR([unsupported machine type]) ;;
esac
else
@@ -82,6 +84,7 @@ case "$target_cpu"-"$platform" in
i386-ieee1275) ;;
powerpc-ieee1275) ;;
sparc64-ieee1275) ;;
+ ia64-efi) ;;
*) AC_MSG_ERROR([unsupported machine type]) ;;
esac
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/fs/fat.c grub2/fs/fat.c
--- grub2.orig/fs/fat.c 2007-08-02 20:40:36.000000000 +0200
+++ grub2/fs/fat.c 2008-01-28 16:29:57.000000000 +0100
@@ -568,7 +568,7 @@ grub_fat_find_dir (grub_disk_t disk, str
continue;
}
- if (grub_strcmp (dirname, filename) == 0)
+ if (grub_strcasecmp (dirname, filename) == 0)
{
if (call_hook)
hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY);
@@ -601,7 +601,7 @@ grub_fat_find_dir (grub_disk_t disk, str
if (hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY))
break;
}
- else if (grub_strcmp (dirname, filename) == 0)
+ else if (grub_strcasecmp (dirname, filename) == 0)
{
if (call_hook)
hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY);
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/geninit.sh grub2/geninit.sh
--- grub2.orig/geninit.sh 2007-07-22 21:17:21.000000000 +0200
+++ grub2/geninit.sh 2008-01-28 16:29:57.000000000 +0100
@@ -49,7 +49,7 @@ EOF
while read line; do
file=`echo $line | cut -f1 -d:`
if echo $@ | grep $file >/dev/null; then
- echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/ grub_\1_init ();/'
+ echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/ grub_\1_init (0);/'
fi
done < ${lst}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/genmk.rb grub2/genmk.rb
--- grub2.orig/genmk.rb 2008-01-25 23:33:56.000000000 +0100
+++ grub2/genmk.rb 2008-01-28 16:29:57.000000000 +0100
@@ -115,7 +115,7 @@ 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 $@
+ $(STRIP) $(STRIP_FLAGS) $@
#{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str}
-rm -f $@
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure 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 2008-01-28 16:29:57.000000000 +0100
@@ -26,25 +26,27 @@
#define GRUB_MOD_INIT(name) \
static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
-void grub_##name##_init (void); \
+void grub_module_##name##_init (grub_dl_t); \
void \
-grub_##name##_init (void) { grub_mod_init (0); } \
+grub_module_##name##_init (grub_dl_t mod) { grub_mod_init (mod); } \
static void \
grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
#define GRUB_MOD_FINI(name) \
static void grub_mod_fini (void) __attribute__ ((used)); \
-void grub_##name##_fini (void); \
+void grub_module_##name##_fini (void); \
void \
-grub_##name##_fini (void) { grub_mod_fini (); } \
+grub_module_##name##_fini (void) { grub_mod_fini (); } \
static void \
grub_mod_fini (void)
#define GRUB_MOD_NAME(name) \
-__asm__ (".section .modname,\"S\"\n.string \"" #name "\"\n.previous")
+static const char grub_module_name_##name[] \
+ __attribute__((section(".modname"), __used__)) = #name
#define GRUB_MOD_DEP(name) \
-__asm__ (".section .moddeps,\"S\"\n.string \"" #name "\"\n.previous")
+static const char grub_module_depend_##name[] \
+ __attribute__((section(".moddeps"), __used__)) = #name
struct grub_dl_segment
{
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/efi/efi.h grub2/include/grub/efi/efi.h
--- grub2.orig/include/grub/efi/efi.h 2007-07-22 01:32:23.000000000 +0200
+++ grub2/include/grub/efi/efi.h 2008-01-28 16:29:57.000000000 +0100
@@ -42,6 +42,13 @@ EXPORT_FUNC(grub_efi_allocate_pages) (gr
grub_efi_uintn_t pages);
void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
grub_efi_uintn_t pages);
+void *
+EXPORT_FUNC(grub_efi_allocate_boot_pages) (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages);
+void
+EXPORT_FUNC(grub_efi_free_boot_pages) (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages);
+
int
EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size,
grub_efi_memory_descriptor_t *memory_map,
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/efi/kernel.h grub2/include/grub/ia64/efi/kernel.h
--- grub2.orig/include/grub/ia64/efi/kernel.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/efi/kernel.h 2008-01-29 05:42:30.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2003,2007,2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#ifndef GRUB_MACHINE_KERNEL_HEADER
+#define GRUB_MACHINE_KERNEL_HEADER 1
+
+/* The prefix which points to the directory where GRUB modules and its
+ configuration file are located. */
+extern char grub_prefix[];
+
+/* The offset of GRUB_PREFIX. */
+#define GRUB_KERNEL_MACHINE_PREFIX 0x8
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END 0x50
+
+#endif /* ! GRUB_MACHINE_KERNEL_HEADER */
+
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/efi/loader.h grub2/include/grub/ia64/efi/loader.h
--- grub2.orig/include/grub/ia64/efi/loader.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/efi/loader.h 2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER 1
+
+/* It is necessary to export these functions, because normal mode commands
+ reuse rescue mode commands. */
+void grub_rescue_cmd_linux (int argc, char *argv[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
+void grub_rescue_cmd_module (int argc, char *argv[]);
+void grub_rescue_cmd_relocate (int argc, char *argv[]);
+void grub_rescue_cmd_fpswa (int argc, char *argv[]);
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/efi/misc.h grub2/include/grub/ia64/efi/misc.h
--- grub2.orig/include/grub/ia64/efi/misc.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/efi/misc.h 2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+void EXPORT_FUNC (memset) (void);
+void EXPORT_FUNC (__ia64_trampoline) (void);
+void EXPORT_FUNC (grub_init_modules) (void);
+
+extern unsigned long EXPORT_VAR (__gp);
+
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/efi/time.h grub2/include/grub/ia64/efi/time.h
--- grub2.orig/include/grub/ia64/efi/time.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/efi/time.h 2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+#ifndef GRUB_MACHINE_TIME_HEADER
+#define GRUB_MACHINE_TIME_HEADER 1
+
+#include
+
+#endif /* ! GRUB_MACHINE_TIME_HEADER */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/setjmp.h grub2/include/grub/ia64/setjmp.h
--- grub2.orig/include/grub/ia64/setjmp.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/setjmp.h 2008-01-29 06:45:08.000000000 +0100
@@ -0,0 +1,31 @@
+/* Define the machine-dependent type `jmp_buf'. Linux/IA-64 version.
+ Copyright (C) 1999, 2000, 2008 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang .
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* User code must not depend on the internal representation of jmp_buf. */
+
+#define _JBLEN 70
+
+/* the __jmp_buf element type should be __float80 per ABI... */
+typedef long grub_jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /* guarantees 128-bit alignment! */
+
+#define grub_setjmp setjmp
+#define grub_longjmp longjmp
+
+int grub_setjmp (grub_jmp_buf env);
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/time.h grub2/include/grub/ia64/time.h
--- grub2.orig/include/grub/ia64/time.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/time.h 2008-01-29 06:45:15.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER 1
+
+static __inline void
+grub_cpu_idle (void)
+{
+ /* FIXME: not implemented */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/types.h grub2/include/grub/ia64/types.h
--- grub2.orig/include/grub/ia64/types.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/types.h 2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER 1
+
+/* The size of void *. */
+#define GRUB_TARGET_SIZEOF_VOID_P 8
+
+/* The size of long. */
+#define GRUB_TARGET_SIZEOF_LONG 8
+
+/* ia64 is little-endian (usually). */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/kernel.h grub2/include/grub/kernel.h
--- grub2.orig/include/grub/kernel.h 2008-01-21 01:04:04.000000000 +0100
+++ grub2/include/grub/kernel.h 2008-01-28 16:29:57.000000000 +0100
@@ -53,7 +53,7 @@ void grub_main (void);
void grub_machine_init (void);
/* The machine-specific finalization. */
-void grub_machine_fini (void);
+void EXPORT_FUNC (grub_machine_fini) (void);
/* The machine-specific prefix initialization. */
void grub_machine_set_prefix (void);
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/misc.h grub2/include/grub/misc.h
--- grub2.orig/include/grub/misc.h 2007-11-05 15:54:00.000000000 +0100
+++ grub2/include/grub/misc.h 2008-01-28 16:29:57.000000000 +0100
@@ -46,6 +46,7 @@ int EXPORT_FUNC(grub_memcmp) (const void
int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2);
int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n);
int EXPORT_FUNC(grub_strncasecmp) (const char *s1, const char *s2, int c);
+int EXPORT_FUNC(grub_strcasecmp) (const char *s1, const char *s2);
char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/dl.c grub2/kern/dl.c
--- grub2.orig/kern/dl.c 2008-01-26 21:34:58.000000000 +0100
+++ grub2/kern/dl.c 2008-01-28 16:29:58.000000000 +0100
@@ -579,6 +579,29 @@ grub_dl_load_core (void *addr, grub_size
return mod;
}
+void
+grub_init_module (const char *name,
+ void (*init)(grub_dl_t), void (*fini)(void))
+{
+ grub_dl_t mod;
+
+ mod = (grub_dl_t) grub_malloc (sizeof (*mod));
+ if (! mod)
+ return;
+
+ mod->name = name;
+ mod->ref_count = 1;
+ mod->dep = 0;
+ mod->segment = 0;
+ mod->init = init;
+ mod->fini = fini;
+
+ grub_dl_call_init (mod);
+
+ /* Can't fail. */
+ grub_dl_add (mod);
+}
+
/* Load a module from the file FILENAME. */
grub_dl_t
grub_dl_load_file (const char *filename)
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/efi/mm.c grub2/kern/efi/mm.c
--- grub2.orig/kern/efi/mm.c 2007-07-22 01:32:26.000000000 +0200
+++ grub2/kern/efi/mm.c 2008-01-28 16:29:58.000000000 +0100
@@ -22,16 +22,14 @@
#include
#include
+//#define DEBUG_MM
+
#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
-#define BYTES_TO_PAGES(bytes) ((bytes) >> 12)
+#define BYTES_TO_PAGES(bytes) ((bytes + 0xfff) >> 12)
#define PAGES_TO_BYTES(pages) ((pages) << 12)
-/* The size of a memory map obtained from the firmware. This must be
- a multiplier of 4KB. */
-#define MEMORY_MAP_SIZE 0x1000
-
/* Maintain the list of allocated pages. */
struct allocated_page
{
@@ -49,11 +47,10 @@ static struct allocated_page *allocated_
#define MIN_HEAP_SIZE 0x100000
#define MAX_HEAP_SIZE (16 * 0x100000)
-
/* Allocate pages. Return the pointer to the first of allocated pages. */
void *
-grub_efi_allocate_pages (grub_efi_physical_address_t address,
- grub_efi_uintn_t pages)
+grub_efi_allocate_boot_pages (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages)
{
grub_efi_allocate_type_t type;
grub_efi_status_t status;
@@ -87,14 +84,34 @@ grub_efi_allocate_pages (grub_efi_physic
{
/* Uggh, the address 0 was allocated... This is too annoying,
so reallocate another one. */
- address = 0xffffffff;
status = b->allocate_pages (type, GRUB_EFI_LOADER_DATA, pages, &address);
- grub_efi_free_pages (0, pages);
+ grub_efi_free_boot_pages (0, pages);
if (status != GRUB_EFI_SUCCESS)
return 0;
}
- if (allocated_pages)
+ return (void *)address;
+}
+
+/* Free pages starting from ADDRESS. */
+void
+grub_efi_free_boot_pages (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages)
+{
+ grub_efi_boot_services_t *b;
+
+ b = grub_efi_system_table->boot_services;
+ b->free_pages (address, pages);
+}
+
+/* Allocate pages. Return the pointer to the first of allocated pages. */
+void *
+grub_efi_allocate_pages (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages)
+{
+ address = grub_efi_allocate_boot_pages (address, pages);
+
+ if (address != 0 && allocated_pages)
{
unsigned i;
@@ -118,8 +135,6 @@ void
grub_efi_free_pages (grub_efi_physical_address_t address,
grub_efi_uintn_t pages)
{
- grub_efi_boot_services_t *b;
-
if (allocated_pages
&& ((grub_efi_physical_address_t) ((grub_addr_t) allocated_pages)
!= address))
@@ -133,9 +148,8 @@ grub_efi_free_pages (grub_efi_physical_a
break;
}
}
-
- b = grub_efi_system_table->boot_services;
- b->free_pages (address, pages);
+
+ grub_efi_free_boot_pages (address, pages);
}
/* Get the memory map as defined in the EFI spec. Return 1 if successful,
@@ -278,7 +292,11 @@ add_memory_regions (grub_efi_memory_desc
grub_efi_uint64_t required_pages)
{
grub_efi_memory_descriptor_t *desc;
-
+
+#ifdef DEBUG_MM
+ grub_printf ("mm: required_pages=%lu\n", required_pages);
+#endif
+
for (desc = memory_map;
desc < memory_map_end;
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
@@ -303,6 +321,10 @@ add_memory_regions (grub_efi_memory_desc
grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
+#ifdef DEBUG_MM
+ grub_printf ("mm: add %lu pages from %p\n", pages, addr);
+#endif
+
required_pages -= pages;
if (required_pages == 0)
break;
@@ -344,6 +366,8 @@ grub_efi_mm_init (void)
grub_efi_uintn_t desc_size;
grub_efi_uint64_t total_pages;
grub_efi_uint64_t required_pages;
+ grub_efi_uintn_t memory_map_size;
+ int res;
/* First of all, allocate pages to maintain allocations. */
allocated_pages
@@ -352,26 +376,35 @@ grub_efi_mm_init (void)
grub_fatal ("cannot allocate memory");
grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
-
+
/* Prepare a memory region to store two memory maps. */
- memory_map = grub_efi_allocate_pages (0,
- 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+ memory_map_size = 0;
+ res = grub_efi_get_memory_map (&memory_map_size, NULL, 0, &desc_size, 0);
+ if (res != 0)
+ grub_fatal ("cannot get memory map size");
+
+ /* Add space for a few more entries as allocating pages can increase
+ memory map size. */
+ memory_map_size += 4 * desc_size;
+
+ memory_map = grub_efi_allocate_pages
+ (0, 2 * BYTES_TO_PAGES (memory_map_size));
if (! memory_map)
grub_fatal ("cannot allocate memory");
- filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE);
+ filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, memory_map_size);
/* Obtain descriptors for available memory. */
- map_size = MEMORY_MAP_SIZE;
+ map_size = memory_map_size;
- if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
+ if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) <= 0)
grub_fatal ("cannot get memory map");
memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
desc_size, memory_map_end);
-
+
/* By default, request a quarter of the available memory. */
total_pages = get_total_pages (filtered_memory_map, desc_size,
filtered_memory_map_end);
@@ -391,7 +424,7 @@ grub_efi_mm_init (void)
#if 0
/* For debug. */
- map_size = MEMORY_MAP_SIZE;
+ map_size = memory_map_size;
if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
grub_fatal ("cannot get memory map");
@@ -404,7 +437,7 @@ grub_efi_mm_init (void)
/* Release the memory maps. */
grub_efi_free_pages ((grub_addr_t) memory_map,
- 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+ 2 * BYTES_TO_PAGES (memory_map_size));
}
void
@@ -420,10 +453,13 @@ grub_efi_mm_fini (void)
p = allocated_pages + i;
if (p->addr != 0)
- grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages);
+ {
+ grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages);
+ }
}
grub_efi_free_pages ((grub_addr_t) allocated_pages,
BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
+ allocated_pages = 0;
}
}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/ia64/efi/elf_ia64_efi.lds grub2/kern/ia64/efi/elf_ia64_efi.lds
--- grub2.orig/kern/ia64/efi/elf_ia64_efi.lds 1970-01-01 01:00:00.000000000 +0100
+++ grub2/kern/ia64/efi/elf_ia64_efi.lds 2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,84 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+OUTPUT_FORMAT("elf64-ia64-little")
+OUTPUT_ARCH(ia64)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x240;
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata.*)
+ /* Reserve space for the entry point descriptor. */
+ . = ALIGN(16);
+ QUAD(0)
+ QUAD(0)
+ }
+ . = ALIGN(0x20);
+ .got :
+ {
+ *(.got.plt)
+ *(.got)
+ . = ALIGN(0x10);
+ }
+ .opd :
+ {
+ *(.opd)
+ }
+ .sdata :
+ {
+ *(.srodata)
+ *(.sdata)
+ *(.sbss)
+ *(.scommon)
+ . = ALIGN(0x10);
+ }
+ .data :
+ {
+ *(.data*)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(0x10);
+ }
+ .dynamic : { *(.dynamic) }
+
+ . = ALIGN(4096);
+ .interp : { *(.interp) }
+ .plt : { *(.plt) }
+ .rela :
+ {
+ *(.rela.text*)
+ *(.rela.data*)
+ *(.rela.sdata)
+ *(.rela.got)
+ }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ /DISCARD/ :
+ {
+ *(.IA_64.unwind*)
+ *(.IA64.unwind*)
+ *(.moddeps)
+ *(.modname)
+ }
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/ia64/efi/init.c grub2/kern/ia64/efi/init.c
--- grub2.orig/kern/ia64/efi/init.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2/kern/ia64/efi/init.c 2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,59 @@
+/* init.c - initialize an ia64-based EFI system */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+void
+grub_machine_init (void)
+{
+ grub_efi_init ();
+ grub_init_modules ();
+}
+
+void
+grub_machine_fini (void)
+{
+ grub_efi_fini ();
+}
+
+void
+grub_machine_set_prefix (void)
+{
+ grub_efi_set_prefix ();
+}
+
+void
+grub_arch_sync_caches (void *address, grub_size_t len)
+{
+ /* Cache line length is at least 32. */
+ grub_uint64_t a = (grub_uint64_t)address & ~0x1f;
+
+ /* Flush data. */
+ for (len = (len + 31) & ~0x1f; len > 0; len -= 0x20, a += 0x20)
+ asm volatile ("fc.i %0" : : "r" (a));
+ /* Sync and serialize. Maybe extra. */
+ asm volatile (";; sync.i;; srlz.i;;");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/ia64/efi/startup.S grub2/kern/ia64/efi/startup.S
--- grub2.orig/kern/ia64/efi/startup.S 1970-01-01 01:00:00.000000000 +0100
+++ grub2/kern/ia64/efi/startup.S 2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+ .text
+ .psr abi64
+ .psr lsb
+ .lsb
+
+ .global _start
+ .proc _start
+_start:
+ alloc loc0=ar.pfs,2,4,0,0
+ mov loc1=rp
+ addl address@hidden(grub_efi_image_handle),gp
+ addl address@hidden(grub_efi_system_table),gp
+ ;;
+ st8 [loc2]=in0
+ st8 [loc3]=in1
+ br.call.sptk.few rp=grub_main
+ ;;
+ mov ar.pfs=loc0
+ mov rp=loc1
+ ;;
+ br.ret.sptk.few rp
+
+ .endp _start
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/ia64/trampoline.S grub2/kern/ia64/trampoline.S
--- grub2.orig/kern/ia64/trampoline.S 1970-01-01 01:00:00.000000000 +0100
+++ grub2/kern/ia64/trampoline.S 2008-01-29 05:43:17.000000000 +0100
@@ -0,0 +1,38 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+ .text
+ .psr abi64
+ .psr lsb
+ .lsb
+
+ .proc __ia64_trampoline
+ .global __ia64_trampoline
+__ia64_trampoline:
+ /* Read address of the real descriptor. */
+ ld8 r2=[r1],8
+ ;;
+ /* Read chain. */
+ ld8 r15=[r1]
+ /* Read pc. */
+ ld8 r3=[r2],8
+ ;;
+ /* Read gp. */
+ ld8 r1=[r2]
+ mov b6=r3
+ br.many b6
+ .endp __ia64_trampoline
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/misc.c grub2/kern/misc.c
--- grub2.orig/kern/misc.c 2008-01-15 18:22:09.000000000 +0100
+++ grub2/kern/misc.c 2008-01-28 16:29:58.000000000 +0100
@@ -193,6 +193,26 @@ grub_strcmp (const char *s1, const char
}
int
+grub_strcasecmp (const char *s1, const char *s2)
+{
+ char c1, c2;
+
+ while (*s1 && *s2)
+ {
+ c1 = grub_tolower (*s1);
+ c2 = grub_tolower (*s2);
+ if (c1 != c2)
+ return (int) c1 - (int) c2;
+
+ s1++;
+ s2++;
+ }
+
+ /* One of these is 0! */
+ return (int) *s1 - (int) *s2;
+}
+
+int
grub_strncmp (const char *s1, const char *s2, grub_size_t n)
{
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/loader/ia64/efi/linux.c grub2/loader/ia64/efi/linux.c
--- grub2.orig/loader/ia64/efi/linux.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2/loader/ia64/efi/linux.c 2008-01-29 05:44:15.000000000 +0100
@@ -0,0 +1,780 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+/* #include */
+#include
+#include
+#include
+#include
+
+#define ALIGN_MIN (256*1024*1024)
+
+#define GRUB_ELF_SEARCH 1024
+
+#define BOOT_PARAM_SIZE 16384
+
+struct ia64_boot_param
+{
+ grub_uint64_t command_line; /* physical address of command line. */
+ grub_uint64_t efi_systab; /* physical address of EFI system table */
+ grub_uint64_t efi_memmap; /* physical address of EFI memory map */
+ grub_uint64_t efi_memmap_size; /* size of EFI memory map */
+ grub_uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */
+ grub_uint32_t efi_memdesc_version; /* memory descriptor version */
+ struct
+ {
+ grub_uint16_t num_cols; /* number of columns on console output dev */
+ grub_uint16_t num_rows; /* number of rows on console output device */
+ grub_uint16_t orig_x; /* cursor's x position */
+ grub_uint16_t orig_y; /* cursor's y position */
+ } console_info;
+ grub_uint64_t fpswa; /* physical address of the fpswa interface */
+ grub_uint64_t initrd_start;
+ grub_uint64_t initrd_size;
+ grub_uint64_t domain_start; /* boot domain address. */
+ grub_uint64_t domain_size; /* how big is the boot domain */
+ grub_uint64_t modules_chain;
+ grub_uint64_t modules_nbr;
+};
+
+struct ia64_boot_module
+{
+ grub_uint64_t mod_start;
+ grub_uint64_t mod_end;
+
+ /* Module command line */
+ grub_uint64_t cmdline;
+
+ grub_uint64_t next;
+};
+
+typedef struct
+{
+ grub_uint32_t revision;
+ grub_uint32_t reserved;
+ void *fpswa;
+} fpswa_interface_t;
+static fpswa_interface_t *fpswa;
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
+ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+static grub_dl_t my_mod;
+
+static int loaded;
+
+/* Kernel base and size. */
+static void *kernel_mem;
+static grub_efi_uintn_t kernel_pages;
+static grub_uint64_t entry;
+
+/* Initrd base and size. */
+static void *initrd_mem;
+static grub_efi_uintn_t initrd_pages;
+static grub_efi_uintn_t initrd_size;
+
+static struct ia64_boot_param *boot_param;
+static grub_efi_uintn_t boot_param_pages;
+static struct ia64_boot_module *last_module = NULL;
+
+/* Can linux kernel be relocated ? */
+#define RELOCATE_OFF 0 /* No. */
+#define RELOCATE_ON 1 /* Yes. */
+#define RELOCATE_FORCE 2 /* Always - used to debug. */
+static int relocate = RELOCATE_OFF;
+
+static inline grub_size_t
+page_align (grub_size_t size)
+{
+ return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
+}
+
+static void
+query_fpswa (void)
+{
+ grub_efi_handle_t fpswa_image;
+ grub_efi_boot_services_t *bs;
+ grub_efi_status_t status;
+ grub_efi_uintn_t size;
+ static const grub_efi_guid_t fpswa_protocol =
+ { 0xc41b6531, 0x97b9, 0x11d3,
+ {0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} };
+
+ if (fpswa != NULL)
+ return;
+
+ size = sizeof(grub_efi_handle_t);
+
+ bs = grub_efi_system_table->boot_services;
+ status = bs->locate_handle (GRUB_EFI_BY_PROTOCOL,
+ &fpswa_protocol,
+ NULL, &size, &fpswa_image);
+ if (status != GRUB_EFI_SUCCESS)
+ {
+ grub_printf("Could not locate FPSWA driver\n");
+ return;
+ }
+ status = bs->handle_protocol (fpswa_image, &fpswa_protocol, &fpswa);
+ if (status != GRUB_EFI_SUCCESS)
+ {
+ grub_printf ("Fpswa protocol not able find the interface\n");
+ return;
+ }
+}
+
+/* Find the optimal number of pages for the memory map. Is it better to
+ move this code to efi/mm.c? */
+static grub_efi_uintn_t
+find_mmap_size (void)
+{
+ static grub_efi_uintn_t mmap_size = 0;
+
+ if (mmap_size != 0)
+ return mmap_size;
+
+ mmap_size = (1 << 12);
+ while (1)
+ {
+ int ret;
+ grub_efi_memory_descriptor_t *mmap;
+ grub_efi_uintn_t desc_size;
+
+ mmap = grub_malloc (mmap_size);
+ if (! mmap)
+ return 0;
+
+ ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+ grub_free (mmap);
+
+ if (ret < 0)
+ grub_fatal ("cannot get memory map");
+ else if (ret > 0)
+ break;
+
+ mmap_size += (1 << 12);
+ }
+
+ /* Increase the size a bit for safety, because GRUB allocates more on
+ later, and EFI itself may allocate more. */
+ mmap_size += (1 << 12);
+
+ return page_align (mmap_size);
+}
+
+static void
+free_pages (void)
+{
+ if (kernel_mem)
+ {
+ grub_efi_free_boot_pages ((grub_addr_t) kernel_mem, kernel_pages);
+ kernel_mem = 0;
+ }
+
+ if (initrd_mem)
+ {
+ grub_efi_free_boot_pages ((grub_addr_t) initrd_mem, initrd_pages);
+ initrd_mem = 0;
+ }
+
+ if (boot_param)
+ {
+ struct ia64_boot_module *mod;
+ struct ia64_boot_module *next_mod;
+
+ /* Free modules. */
+ mod = (struct ia64_boot_module *)boot_param->modules_chain;
+ while (mod != 0)
+ {
+ next_mod = (struct ia64_boot_module *)mod->next;
+
+ grub_efi_free_boot_pages
+ (mod->mod_start, page_align (mod->mod_end - mod->mod_start) >> 12);
+ grub_efi_free_boot_pages ((grub_efi_physical_address_t)mod, 1);
+
+ mod = next_mod;
+ }
+
+ /* Free bootparam. */
+ grub_efi_free_boot_pages ((grub_efi_physical_address_t)boot_param,
+ boot_param_pages);
+ boot_param = 0;
+ }
+}
+
+static void *
+allocate_pages (grub_uint64_t align, grub_uint64_t size_pages,
+ grub_uint64_t nobase)
+{
+ grub_uint64_t size;
+ grub_efi_uintn_t desc_size;
+ grub_efi_memory_descriptor_t *mmap, *mmap_end;
+ grub_efi_uintn_t mmap_size, tmp_mmap_size;
+ grub_efi_memory_descriptor_t *desc;
+ void *mem = NULL;
+
+ size = size_pages << 12;
+
+ mmap_size = find_mmap_size ();
+
+ /* Read the memory map temporarily, to find free space. */
+ mmap = grub_malloc (mmap_size);
+ if (! mmap)
+ return 0;
+
+ tmp_mmap_size = mmap_size;
+ if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0)
+ grub_fatal ("cannot get memory map");
+
+ mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
+
+ /* First, find free pages for the real mode code
+ and the memory map buffer. */
+ for (desc = mmap;
+ desc < mmap_end;
+ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+ {
+ grub_uint64_t start, end;
+ grub_uint64_t aligned_start;
+
+ if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
+ continue;
+
+ start = desc->physical_start;
+ end = start + (desc->num_pages << 12);
+ /* Align is a power of 2. */
+ aligned_start = (start + align - 1) & ~(align - 1);
+ if (aligned_start + size > end)
+ continue;
+ if (aligned_start == nobase)
+ aligned_start += align;
+ if (aligned_start + size > end)
+ continue;
+ mem = grub_efi_allocate_pages (aligned_start, size_pages);
+ if (! mem)
+ grub_fatal ("cannot allocate pages");
+ break;
+ }
+
+ if (! mem)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory");
+ goto fail;
+ }
+
+ grub_free (mmap);
+ return mem;
+
+ fail:
+ grub_free (mmap);
+ free_pages ();
+ return 0;
+}
+
+static void
+set_boot_param_console (void)
+{
+ grub_efi_simple_text_output_interface_t *conout;
+ grub_efi_uintn_t cols, rows;
+
+ conout = grub_efi_system_table->con_out;
+ if (conout->query_mode (conout, conout->mode->mode, &cols, &rows)
+ != GRUB_EFI_SUCCESS)
+ return;
+
+ grub_dprintf("linux",
+ "Console info: cols=%lu rows=%lu x=%u y=%u\n",
+ cols, rows,
+ conout->mode->cursor_column, conout->mode->cursor_row);
+
+ boot_param->console_info.num_cols = cols;
+ boot_param->console_info.num_rows = rows;
+ boot_param->console_info.orig_x = conout->mode->cursor_column;
+ boot_param->console_info.orig_y = conout->mode->cursor_row;
+}
+
+static grub_err_t
+grub_linux_boot (void)
+{
+ grub_efi_uintn_t mmap_size;
+ grub_efi_uintn_t map_key;
+ grub_efi_uintn_t desc_size;
+ grub_efi_uint32_t desc_version;
+ grub_efi_memory_descriptor_t *mmap_buf;
+
+ /* FPSWA. */
+ query_fpswa ();
+ boot_param->fpswa = (grub_uint64_t)fpswa;
+
+ /* Initrd. */
+ boot_param->initrd_start = (grub_uint64_t)initrd_mem;
+ boot_param->initrd_size = (grub_uint64_t)initrd_size;
+
+ set_boot_param_console ();
+
+ grub_printf ("Jump to %016lx\n", entry);
+
+ grub_machine_fini ();
+
+ /* MDT.
+ Must be done after grub_machine_fini because map_key is used by
+ exit_boot_services. */
+ mmap_size = find_mmap_size ();
+ mmap_buf = grub_efi_allocate_boot_pages (0, page_align (mmap_size) >> 12);
+ if (! mmap_buf)
+ grub_fatal ("cannot allocate memory map");
+ if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+ &desc_size, &desc_version) <= 0)
+ grub_fatal ("cannot get memory map");
+
+ boot_param->efi_memmap = (grub_uint64_t)mmap_buf;
+ boot_param->efi_memmap_size = mmap_size;
+ boot_param->efi_memdesc_size = desc_size;
+ boot_param->efi_memdesc_version = desc_version;
+
+ if (! grub_efi_exit_boot_services (map_key))
+ grub_fatal ("cannot exit boot services");
+
+ /* See you next boot. */
+ asm volatile ("mov r28=%1; br.sptk.few %0" :: "b"(entry),"r"(boot_param));
+
+ /* Never reach here. */
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+ free_pages ();
+ grub_dl_unref (my_mod);
+ loaded = 0;
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_load_elf64 (grub_file_t file, void *buffer)
+{
+ Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer;
+ Elf64_Phdr *phdr;
+ int i;
+ grub_uint64_t low_addr;
+ grub_uint64_t high_addr;
+ grub_uint64_t align;
+ grub_uint64_t reloc_offset;
+
+ if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
+ return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
+
+ if (ehdr->e_ident[EI_MAG0] != ELFMAG0
+ || ehdr->e_ident[EI_MAG1] != ELFMAG1
+ || ehdr->e_ident[EI_MAG2] != ELFMAG2
+ || ehdr->e_ident[EI_MAG3] != ELFMAG3
+ || ehdr->e_version != EV_CURRENT
+ || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
+ || ehdr->e_machine != EM_IA_64)
+ return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
+
+ if (ehdr->e_type != ET_EXEC)
+ return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
+
+ /* FIXME: Should we support program headers at strange locations? */
+ if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > GRUB_ELF_SEARCH)
+ return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
+
+ entry = ehdr->e_entry;
+
+ /* Compute low, high and align addresses. */
+ low_addr = ~0UL;
+ high_addr = 0;
+ align = 0;
+ for (i = 0; i < ehdr->e_phnum; i++)
+ {
+ phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff
+ + i * ehdr->e_phentsize);
+ if (phdr->p_type == PT_LOAD)
+ {
+ if (phdr->p_paddr < low_addr)
+ low_addr = phdr->p_paddr;
+ if (phdr->p_paddr + phdr->p_memsz > high_addr)
+ high_addr = phdr->p_paddr + phdr->p_memsz;
+ if (phdr->p_align > align)
+ align = phdr->p_align;
+ }
+ }
+
+ if (align < ALIGN_MIN)
+ align = ALIGN_MIN;
+
+ if (high_addr == 0)
+ return grub_error (GRUB_ERR_BAD_OS, "no program entries");
+
+ kernel_pages = page_align (high_addr - low_addr) >> 12;
+
+ if (relocate != RELOCATE_FORCE)
+ {
+ kernel_mem = grub_efi_allocate_boot_pages (low_addr, kernel_pages);
+ reloc_offset = 0;
+ }
+ /* Try to relocate. */
+ if (! kernel_mem && relocate != RELOCATE_OFF)
+ {
+ kernel_mem = allocate_pages (align, kernel_pages, low_addr);
+ if (kernel_mem)
+ {
+ reloc_offset = kernel_mem - low_addr;
+ grub_printf (" Relocated at %p (offset=%016llx)\n",
+ kernel_mem, reloc_offset);
+ entry += reloc_offset;
+ }
+ }
+ if (! kernel_mem)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "cannot allocate memory for OS");
+
+ /* Load every loadable segment in memory. */
+ for (i = 0; i < ehdr->e_phnum; i++)
+ {
+ phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff
+ + i * ehdr->e_phentsize);
+ if (phdr->p_type == PT_LOAD)
+ {
+ grub_printf (" [paddr=%llx load=%llx memsz=%08llx "
+ "off=%lx flags=%x]\n",
+ phdr->p_paddr, phdr->p_paddr + reloc_offset,
+ phdr->p_memsz, phdr->p_offset, phdr->p_flags);
+
+ if (grub_file_seek (file, phdr->p_offset) == -1)
+ return grub_error (GRUB_ERR_BAD_OS,
+ "invalid offset in program header");
+
+ if (grub_file_read (file, (void *)(phdr->p_paddr + reloc_offset),
+ phdr->p_filesz)
+ != (grub_ssize_t) phdr->p_filesz)
+ return grub_error (GRUB_ERR_BAD_OS,
+ "couldn't read segment from file");
+
+ if (phdr->p_filesz < phdr->p_memsz)
+ grub_memset
+ ((char *)(phdr->p_paddr + reloc_offset + phdr->p_filesz),
+ 0, phdr->p_memsz - phdr->p_filesz);
+
+ /* Sync caches if necessary. */
+ if (phdr->p_flags & PF_X)
+ grub_arch_sync_caches
+ ((void *)(phdr->p_paddr + reloc_offset), phdr->p_memsz);
+ }
+ }
+ loaded = 1;
+ return 0;
+}
+
+void
+grub_rescue_cmd_linux (int argc, char *argv[])
+{
+ grub_file_t file = 0;
+ char buffer[GRUB_ELF_SEARCH];
+ char *cmdline, *p;
+ grub_ssize_t len;
+ int i;
+
+ grub_dl_ref (my_mod);
+
+ grub_loader_unset ();
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
+ goto fail;
+ }
+
+ file = grub_gzfile_open (argv[0], 1);
+ if (! file)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file");
+ goto fail;
+ }
+
+ len = grub_file_read (file, buffer, sizeof (buffer));
+ if (len < (grub_ssize_t)sizeof (Elf64_Ehdr))
+ {
+ grub_error (GRUB_ERR_BAD_OS, "File too small");
+ goto fail;
+ }
+
+ grub_printf ("Loading linux: %s\n", argv[0]);
+
+ if (grub_load_elf64 (file, buffer))
+ goto fail;
+
+ len = sizeof("BOOT_IMAGE=") + 8;
+ for (i = 0; i < argc; i++)
+ len += grub_strlen (argv[i]) + 1;
+ len += sizeof (struct ia64_boot_param) + 256; /* Room for extensions. */
+ boot_param_pages = page_align (len) >> 12;
+ boot_param = grub_efi_allocate_boot_pages (0, boot_param_pages);
+ if (boot_param == 0)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "cannot allocate memory for bootparams");
+ goto fail;
+ }
+
+ grub_memset (boot_param, 0, len);
+ cmdline = ((char *)(boot_param + 1)) + 256;
+
+ /* Build cmdline. */
+ p = grub_stpcpy (cmdline, "BOOT_IMAGE");
+ for (i = 0; i < argc; i++)
+ {
+ *p++ = ' ';
+ p = grub_stpcpy (p, argv[i]);
+ }
+ cmdline[10] = '=';
+
+ boot_param->command_line = (grub_uint64_t)cmdline;
+ boot_param->efi_systab = (grub_uint64_t)grub_efi_system_table;
+
+ grub_errno = GRUB_ERR_NONE;
+
+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
+
+ fail:
+ if (file)
+ grub_file_close (file);
+
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+ grub_efi_free_boot_pages ((grub_efi_physical_address_t)boot_param,
+ boot_param_pages);
+ grub_dl_unref (my_mod);
+ }
+}
+
+void
+grub_rescue_cmd_initrd (int argc, char *argv[])
+{
+ grub_file_t file = 0;
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+ goto fail;
+ }
+
+ if (! loaded)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+ goto fail;
+ }
+
+ file = grub_gzfile_open (argv[0], 1);
+ if (! file)
+ goto fail;
+
+ grub_printf ("Loading initrd: %s\n",argv[0]);
+
+ initrd_size = grub_file_size (file);
+ initrd_pages = (page_align (initrd_size) >> 12);
+ initrd_mem = grub_efi_allocate_boot_pages (0, initrd_pages);
+ if (! initrd_mem)
+ grub_fatal ("cannot allocate pages");
+
+ grub_printf (" [addr=0x%lx, size=0x%lx]\n",
+ (grub_uint64_t)initrd_mem, initrd_size);
+
+ if (grub_file_read (file, initrd_mem, initrd_size)
+ != (grub_ssize_t)initrd_size)
+ {
+ grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+ goto fail;
+ }
+ fail:
+ if (file)
+ grub_file_close (file);
+}
+
+void
+grub_rescue_cmd_module (int argc, char *argv[])
+{
+ grub_file_t file = 0;
+ grub_ssize_t size, len = 0;
+ char *module = 0, *cmdline = 0, *p;
+ struct ia64_boot_module *mod = NULL;
+ int i;
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+ goto fail;
+ }
+
+ if (!boot_param)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "You need to load the multiboot kernel first");
+ goto fail;
+ }
+
+ file = grub_gzfile_open (argv[0], 1);
+ if (! file)
+ goto fail;
+
+ size = grub_file_size (file);
+ module = grub_efi_allocate_boot_pages (0, page_align (size) >> 12);
+ if (! module)
+ goto fail;
+
+ grub_printf ("Module %s [addr=%llx + %lx]\n",
+ argv[0], (grub_uint64_t)module, size);
+
+ if (grub_file_read (file, module, size) != size)
+ {
+ grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+ goto fail;
+ }
+
+ len = sizeof (struct ia64_boot_module);
+ for (i = 0; i < argc; i++)
+ len += grub_strlen (argv[i]) + 1;
+
+ if (len > 4096)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "module command line too long");
+ goto fail;
+ }
+ mod = grub_efi_allocate_boot_pages (0, 1);
+ if (! mod)
+ goto fail;
+
+ p = (char *)(mod + 1);
+
+ mod->mod_start = (grub_uint64_t)module;
+ mod->mod_end = (grub_uint64_t)module + size;
+ mod->cmdline = (grub_uint64_t)p;
+ mod->next = 0;
+
+ if (last_module)
+ last_module->next = (grub_uint64_t)mod;
+ else
+ {
+ last_module = mod;
+ boot_param->modules_chain = (grub_uint64_t)mod;
+ }
+ boot_param->modules_nbr++;
+
+ /* Copy command line. */
+ for (i = 0; i < argc; i++)
+ {
+ p = grub_stpcpy (p, argv[i]);
+ *(p++) = ' ';
+ }
+
+ /* Remove the space after the last word. */
+ *(--p) = '\0';
+
+
+ fail:
+ if (file)
+ grub_file_close (file);
+
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+ grub_free (module);
+ grub_free (cmdline);
+ }
+}
+
+void
+grub_rescue_cmd_relocate (int argc, char *argv[])
+{
+ static const char * const vals[] = { "off", "on", "force"};
+ unsigned int i;
+
+ if (argc == 0)
+ {
+ grub_printf ("relocate is %s\n", vals[relocate]);
+ }
+ else if (argc == 1)
+ {
+ if (kernel_mem != NULL)
+ grub_printf ("Warning: kernel already loaded!\n");
+ for (i = 0; i < sizeof (vals)/sizeof(vals[0]); i++)
+ if (grub_strcmp (argv[0], vals[i]) == 0)
+ {
+ relocate = i;
+ return;
+ }
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown relocate value");
+ }
+ else
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "accept 0 or 1 argument");
+ }
+}
+
+
+void
+grub_rescue_cmd_fpswa (int argc, char *argv[] __attribute__((unused)))
+{
+ if (argc != 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Arguments not expected");
+ return;
+ }
+ query_fpswa ();
+ if (fpswa == NULL)
+ grub_printf ("No FPSWA loaded\n");
+ else
+ grub_printf ("FPSWA revision: %x\n", fpswa->revision);
+}
+
+GRUB_MOD_INIT(linux)
+{
+ grub_rescue_register_command ("linux",
+ grub_rescue_cmd_linux,
+ "load linux");
+ grub_rescue_register_command ("initrd",
+ grub_rescue_cmd_initrd,
+ "load initrd");
+ grub_rescue_register_command ("module", grub_rescue_cmd_module,
+ "load a multiboot module");
+ grub_rescue_register_command ("relocate", grub_rescue_cmd_relocate,
+ "set relocate feature");
+ grub_rescue_register_command ("fpswa", grub_rescue_cmd_fpswa,
+ "load fpswa");
+ my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+ grub_rescue_unregister_command ("linux");
+ grub_rescue_unregister_command ("initrd");
+ grub_rescue_unregister_command ("module");
+ grub_rescue_unregister_command ("relocate");
+ grub_rescue_unregister_command ("fpswa");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/loader/ia64/efi/linux_normal.c grub2/loader/ia64/efi/linux_normal.c
--- grub2.orig/loader/ia64/efi/linux_normal.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2/loader/ia64/efi/linux_normal.c 2008-01-29 05:45:15.000000000 +0100
@@ -0,0 +1,107 @@
+/* linux_normal.c - boot linux */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+static grub_err_t
+grub_normal_linux_command (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_rescue_cmd_linux (argc, args);
+ return grub_errno;
+}
+
+
+static grub_err_t
+grub_normal_initrd_command (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_rescue_cmd_initrd (argc, args);
+ return grub_errno;
+}
+
+static grub_err_t
+grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_rescue_cmd_module (argc, args);
+ return grub_errno;
+}
+
+static grub_err_t
+grub_normal_cmd_relocate (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_rescue_cmd_relocate (argc, args);
+ return grub_errno;
+}
+
+static grub_err_t
+grub_normal_cmd_fpswa (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_rescue_cmd_fpswa (argc, args);
+ return grub_errno;
+}
+
+GRUB_MOD_INIT(linux_normal)
+{
+ (void) mod; /* To stop warning. */
+ grub_register_command
+ ("linux", grub_normal_linux_command,
+ GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+ "linux FILE [ARGS...]",
+ "Load a linux kernel.", 0);
+
+ grub_register_command
+ ("initrd", grub_normal_initrd_command,
+ GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+ "initrd FILE",
+ "Load an initrd.", 0);
+
+ grub_register_command
+ ("module", grub_normal_cmd_module,
+ GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+ "module FILE [ARGS...]",
+ "Load a Multiboot module.", 0);
+
+ grub_register_command
+ ("relocate", grub_normal_cmd_relocate,
+ GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+ "relocate [on|off|force]",
+ "Set relocate feature.", 0);
+
+ grub_register_command
+ ("fpswa", grub_normal_cmd_fpswa,
+ GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+ "fpswa",
+ "Display FPSWA version.", 0);
+}
+
+GRUB_MOD_FINI(linux_normal)
+{
+ grub_unregister_command ("linux");
+ grub_unregister_command ("initrd");
+ grub_unregister_command ("module");
+ grub_unregister_command ("relocate");
+ grub_unregister_command ("fpswa");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/normal/ia64/longjmp.S grub2/normal/ia64/longjmp.S
--- grub2.orig/normal/ia64/longjmp.S 1970-01-01 01:00:00.000000000 +0100
+++ grub2/normal/ia64/longjmp.S 2008-01-29 06:13:19.000000000 +0100
@@ -0,0 +1,162 @@
+/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang .
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA.
+
+ Note that __sigsetjmp() did NOT flush the register stack. Instead,
+ we do it here since __longjmp() is usually much less frequently
+ invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp()
+ didn't (and wouldn't be able to) save ar.rnat either. This is a problem
+ because if we're not careful, we could end up loading random NaT bits.
+ There are two cases:
+
+ (i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ ar.rnat contains the desired bits---preserve ar.rnat
+ across loadrs and write to ar.bspstore
+
+ (ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ The desired ar.rnat is stored in
+ ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those
+ bits into ar.rnat after setting ar.bspstore. */
+
+
+
+# define pPos p6 /* is rotate count positive? */
+# define pNeg p7 /* is rotate count negative? */
+
+
+ /* __longjmp(__jmp_buf buf, int val) */
+
+ .text
+ .global longjmp
+ .proc longjmp
+longjmp:
+ alloc r8=ar.pfs,2,1,0,0
+ mov r27=ar.rsc
+ add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr
+ ;;
+ ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr
+ mov r10=ar.bsp
+ and r11=~0x3,r27 // clear ar.rsc.mode
+ ;;
+ flushrs // flush dirty regs to backing store (must be first in insn grp)
+ ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp
+ sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf
+ ;;
+ ld8 r25=[r2] // r25 <- jmpbuf.ar_unat
+ extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f
+ ;;
+ cmp.lt pNeg,pPos=r8,r0
+ mov r2=in0
+ ;;
+(pPos) mov r16=r8
+(pNeg) add r16=64,r8
+(pPos) sub r17=64,r8
+(pNeg) sub r17=r0,r8
+ ;;
+ mov ar.rsc=r11 // put RSE in enforced lazy mode
+ shr.u r8=r25,r16
+ add r3=8,in0 // r3 <- &jmpbuf.r1
+ shl r9=r25,r17
+ ;;
+ or r25=r8,r9
+ ;;
+ mov r26=ar.rnat
+ mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12)
+ ;;
+ ld8.fill.nta sp=[r2],16 // r12 (sp)
+ ld8.fill.nta gp=[r3],16 // r1 (gp)
+ dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ ;;
+ ld8.nta r16=[r2],16 // caller's unat
+ ld8.nta r17=[r3],16 // fpsr
+ ;;
+ ld8.fill.nta r4=[r2],16 // r4
+ ld8.fill.nta r5=[r3],16 // r5 (gp)
+ cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp)
+ ;;
+ ld8.fill.nta r6=[r2],16 // r6
+ ld8.fill.nta r7=[r3],16 // r7
+ ;;
+ mov ar.unat=r16 // restore caller's unat
+ mov ar.fpsr=r17 // restore fpsr
+ ;;
+ ld8.nta r16=[r2],16 // b0
+ ld8.nta r17=[r3],16 // b1
+ ;;
+(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ mov ar.bspstore=r23 // restore ar.bspstore
+ ;;
+ ld8.nta r18=[r2],16 // b2
+ ld8.nta r19=[r3],16 // b3
+ ;;
+ ld8.nta r20=[r2],16 // b4
+ ld8.nta r21=[r3],16 // b5
+ ;;
+ ld8.nta r11=[r2],16 // ar.pfs
+ ld8.nta r22=[r3],56 // ar.lc
+ ;;
+ ld8.nta r24=[r2],32 // pr
+ mov b0=r16
+ ;;
+ ldf.fill.nta f2=[r2],32
+ ldf.fill.nta f3=[r3],32
+ mov b1=r17
+ ;;
+ ldf.fill.nta f4=[r2],32
+ ldf.fill.nta f5=[r3],32
+ mov b2=r18
+ ;;
+ ldf.fill.nta f16=[r2],32
+ ldf.fill.nta f17=[r3],32
+ mov b3=r19
+ ;;
+ ldf.fill.nta f18=[r2],32
+ ldf.fill.nta f19=[r3],32
+ mov b4=r20
+ ;;
+ ldf.fill.nta f20=[r2],32
+ ldf.fill.nta f21=[r3],32
+ mov b5=r21
+ ;;
+ ldf.fill.nta f22=[r2],32
+ ldf.fill.nta f23=[r3],32
+ mov ar.lc=r22
+ ;;
+ ldf.fill.nta f24=[r2],32
+ ldf.fill.nta f25=[r3],32
+ cmp.eq p8,p9=0,in1
+ ;;
+ ldf.fill.nta f26=[r2],32
+ ldf.fill.nta f27=[r3],32
+ mov ar.pfs=r11
+ ;;
+ ldf.fill.nta f28=[r2],32
+ ldf.fill.nta f29=[r3],32
+ ;;
+ ldf.fill.nta f30=[r2]
+ ldf.fill.nta f31=[r3]
+(p8) mov r8=1
+
+ mov ar.rnat=r26 // restore ar.rnat
+ ;;
+ mov ar.rsc=r27 // restore ar.rsc
+(p9) mov r8=in1
+
+ invala // virt. -> phys. regnum mapping may change
+ mov pr=r24,-1
+ br.ret.dptk.few rp
+ .endp longjmp
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/normal/ia64/setjmp.S grub2/normal/ia64/setjmp.S
--- grub2.orig/normal/ia64/setjmp.S 1970-01-01 01:00:00.000000000 +0100
+++ grub2/normal/ia64/setjmp.S 2008-01-29 06:13:12.000000000 +0100
@@ -0,0 +1,171 @@
+/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang .
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA.
+
+ The layout of the jmp_buf is as follows. This is subject to change
+ and user-code should never depend on the particular layout of
+ jmp_buf!
+
+
+ offset: description:
+ ------- ------------
+ 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS)
+ 0x008 r1 (gp)
+ 0x010 caller's unat
+ 0x018 fpsr
+ 0x020 r4
+ 0x028 r5
+ 0x030 r6
+ 0x038 r7
+ 0x040 rp (b0)
+ 0x048 b1
+ 0x050 b2
+ 0x058 b3
+ 0x060 b4
+ 0x068 b5
+ 0x070 ar.pfs
+ 0x078 ar.lc
+ 0x080 pr
+ 0x088 ar.bsp ; unchangeable (see __longjmp.S)
+ 0x090 ar.unat
+ 0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat)
+ 0x0a0 f2
+ 0x0b0 f3
+ 0x0c0 f4
+ 0x0d0 f5
+ 0x0e0 f16
+ 0x0f0 f17
+ 0x100 f18
+ 0x110 f19
+ 0x120 f20
+ 0x130 f21
+ 0x130 f22
+ 0x140 f23
+ 0x150 f24
+ 0x160 f25
+ 0x170 f26
+ 0x180 f27
+ 0x190 f28
+ 0x1a0 f29
+ 0x1b0 f30
+ 0x1c0 f31 */
+
+
+ /* The following two entry points are the traditional entry points: */
+
+ .text
+ .global setjmp
+ .proc setjmp
+setjmp:
+ alloc r8=ar.pfs,2,0,0,0
+ mov in1=1
+ br.cond.sptk.many __sigsetjmp
+ .endp setjmp
+
+ /* __sigsetjmp(__jmp_buf buf, int savemask) */
+
+ .proc __sigsetjmp
+__sigsetjmp:
+ //.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
+ alloc loc1=ar.pfs,2,2,2,0
+ mov r16=ar.unat
+ ;;
+ mov r17=ar.fpsr
+ mov r2=in0
+ add r3=8,in0
+ ;;
+ st8.spill.nta [r2]=sp,16 // r12 (sp)
+ st8.spill.nta [r3]=gp,16 // r1 (gp)
+ ;;
+ st8.nta [r2]=r16,16 // save caller's unat
+ st8.nta [r3]=r17,16 // save fpsr
+ add r8=0xa0,in0
+ ;;
+ st8.spill.nta [r2]=r4,16 // r4
+ st8.spill.nta [r3]=r5,16 // r5
+ add r9=0xb0,in0
+ ;;
+ stf.spill.nta [r8]=f2,32
+ stf.spill.nta [r9]=f3,32
+ mov loc0=rp
+ .body
+ ;;
+ stf.spill.nta [r8]=f4,32
+ stf.spill.nta [r9]=f5,32
+ mov r17=b1
+ ;;
+ stf.spill.nta [r8]=f16,32
+ stf.spill.nta [r9]=f17,32
+ mov r18=b2
+ ;;
+ stf.spill.nta [r8]=f18,32
+ stf.spill.nta [r9]=f19,32
+ mov r19=b3
+ ;;
+ stf.spill.nta [r8]=f20,32
+ stf.spill.nta [r9]=f21,32
+ mov r20=b4
+ ;;
+ stf.spill.nta [r8]=f22,32
+ stf.spill.nta [r9]=f23,32
+ mov r21=b5
+ ;;
+ stf.spill.nta [r8]=f24,32
+ stf.spill.nta [r9]=f25,32
+ mov r22=ar.lc
+ ;;
+ stf.spill.nta [r8]=f26,32
+ stf.spill.nta [r9]=f27,32
+ mov r24=pr
+ ;;
+ stf.spill.nta [r8]=f28,32
+ stf.spill.nta [r9]=f29,32
+ ;;
+ stf.spill.nta [r8]=f30
+ stf.spill.nta [r9]=f31
+
+ st8.spill.nta [r2]=r6,16 // r6
+ st8.spill.nta [r3]=r7,16 // r7
+ ;;
+ mov r23=ar.bsp
+ mov r25=ar.unat
+ mov out0=in0
+
+ st8.nta [r2]=loc0,16 // b0
+ st8.nta [r3]=r17,16 // b1
+ mov out1=in1
+ ;;
+ st8.nta [r2]=r18,16 // b2
+ st8.nta [r3]=r19,16 // b3
+ ;;
+ st8.nta [r2]=r20,16 // b4
+ st8.nta [r3]=r21,16 // b5
+ ;;
+ st8.nta [r2]=loc1,16 // ar.pfs
+ st8.nta [r3]=r22,16 // ar.lc
+ ;;
+ st8.nta [r2]=r24,16 // pr
+ st8.nta [r3]=r23,16 // ar.bsp
+ ;;
+ st8.nta [r2]=r25 // ar.unat
+ st8.nta [r3]=in0 // &__jmp_buf
+ mov r8=0
+ mov rp=loc0
+ mov ar.pfs=loc1
+ br.ret.sptk.many rp
+
+ .endp __sigsetjmp
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/util/ia64/efi/elf2pe.c grub2/util/ia64/efi/elf2pe.c
--- grub2.orig/util/ia64/efi/elf2pe.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2/util/ia64/efi/elf2pe.c 2008-01-29 06:41:55.000000000 +0100
@@ -0,0 +1,812 @@
+/* elf2pe.c - convert elf binary to PE/Coff. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if defined(ELF2PE_I386)
+#define USE_ELF32
+#define USE_PE32
+#define ELF_MACHINE EM_386
+#define EFI_MACHINE PE32_MACHINE_I386
+#elif defined(ELF2PE_IA64)
+#define USE_ELF64
+#define USE_PE32PLUS
+#define ELF_MACHINE EM_IA_64
+#define EFI_MACHINE PE32_MACHINE_IA64
+#else
+#error "unknown architecture"
+#endif
+
+#include "pe32.h"
+
+const char *filename;
+
+int
+is_elf_header(uint8_t *buffer)
+{
+ return (buffer[EI_MAG0] == ELFMAG0
+ && buffer[EI_MAG1] == ELFMAG1
+ && buffer[EI_MAG2] == ELFMAG2
+ && buffer[EI_MAG3] == ELFMAG3);
+}
+
+#ifdef USE_ELF32
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Rel Elf_Rel;
+typedef Elf32_Rela Elf_Rela;
+typedef Elf32_Sym Elf_Sym;
+#define ELFCLASS ELFCLASS32
+#define ELF_R_TYPE(r) ELF32_R_TYPE(r)
+#define ELF_R_SYM(r) ELF32_R_SYM(r)
+#else
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Rel Elf_Rel;
+typedef Elf64_Rela Elf_Rela;
+typedef Elf64_Sym Elf_Sym;
+#define ELFCLASS ELFCLASS64
+#define ELF_R_TYPE(r) ELF64_R_TYPE(r)
+#define ELF_R_SYM(r) ELF64_R_SYM(r)
+#endif
+
+#ifdef __ia64__
+#define ELF_ETYPE ET_DYN
+#else
+#define ELF_ETYPE ET_EXEC
+#endif
+
+/* Well known ELF structures. */
+Elf_Ehdr *ehdr;
+Elf_Shdr *shdr_base;
+Elf_Shdr *shdr_dynamic;
+const uint8_t *shdr_str;
+
+/* PE section alignment. */
+const uint32_t coff_alignment = 0x20;
+const uint32_t coff_nbr_sections = 4;
+
+/* Current offset in coff file. */
+uint32_t coff_offset;
+
+/* Result Coff file in memory. */
+uint8_t *coff_file;
+
+/* Offset in Coff file of headers and sections. */
+uint32_t nt_hdr_offset;
+uint32_t table_offset;
+uint32_t text_offset;
+uint32_t data_offset;
+uint32_t reloc_offset;
+
+#ifdef __ia64__
+uint32_t coff_entry_descr_offset;
+uint32_t coff_entry_descr_func;
+uint64_t plt_base;
+#endif
+
+/* ELF sections to offset in Coff file. */
+uint32_t *coff_sections_offset;
+
+struct pe32_fixup_block *coff_base_rel;
+uint16_t *coff_entry_rel;
+
+uint32_t
+coff_align(uint32_t offset)
+{
+ return (offset + coff_alignment - 1) & ~(coff_alignment - 1);
+}
+
+Elf_Shdr *
+get_shdr_by_index(uint32_t num)
+{
+ if (num >= ehdr->e_shnum)
+ return NULL;
+ return (Elf_Shdr*)((uint8_t*)shdr_base + num * ehdr->e_shentsize);
+}
+
+int
+check_elf_header (void)
+{
+ /* Note: Magic has already been tested. */
+ if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
+ return 0;
+ if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
+ return 0;
+ if (ehdr->e_type != ELF_ETYPE)
+ return 0;
+ if (ehdr->e_machine != ELF_MACHINE)
+ return 0;
+ if (ehdr->e_version != EV_CURRENT)
+ return 0;
+
+ shdr_base = (Elf_Shdr *)((uint8_t *)ehdr + ehdr->e_shoff);
+
+ coff_sections_offset =
+ (uint32_t *)malloc (ehdr->e_shnum * sizeof (uint32_t));
+ memset (coff_sections_offset, 0, ehdr->e_shnum * sizeof(uint32_t));
+
+ if (ehdr->e_shstrndx != SHN_UNDEF)
+ shdr_str = (uint8_t*)ehdr + shdr_base[ehdr->e_shstrndx].sh_offset;
+ else
+ shdr_str = NULL;
+
+ return 1;
+}
+
+int
+is_text_shdr (Elf_Shdr *shdr)
+{
+ if (shdr->sh_type != SHT_PROGBITS) {
+ return 0;
+ }
+#ifdef __ia64__
+ return (shdr->sh_flags & (SHF_EXECINSTR | SHF_ALLOC))
+ == (SHF_ALLOC | SHF_EXECINSTR);
+#else
+ return (shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC;
+#endif
+}
+
+int
+is_data_shdr (Elf_Shdr *shdr)
+{
+ if (shdr->sh_type != SHT_PROGBITS && shdr->sh_type != SHT_NOBITS) {
+ return 0;
+ }
+ return (shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);
+}
+
+void
+create_section_header (const char *name, uint32_t offset, uint32_t size,
+ uint32_t flags)
+{
+ struct pe32_section_header *hdr;
+ hdr = (struct pe32_section_header*)(coff_file + table_offset);
+
+ strcpy (hdr->name, name);
+ hdr->virtual_size = size;
+ hdr->virtual_address = offset;
+ hdr->raw_data_size = size;
+ hdr->raw_data_offset = offset;
+ hdr->relocations_offset = 0;
+ hdr->line_numbers_offset = 0;
+ hdr->num_relocations = 0;
+ hdr->num_line_numbers = 0;
+ hdr->characteristics = flags;
+
+ table_offset += sizeof (struct pe32_section_header);
+}
+
+int
+scan_sections (void)
+{
+ uint32_t i;
+ struct pe32_dos_header *doshdr;
+ struct pe32_nt_header *nt_hdr;
+ uint32_t coff_entry = 0;
+ int status = 0;
+
+ coff_offset = 0;
+
+ /* Coff file start with a DOS header. */
+ coff_offset = sizeof(struct pe32_dos_header);
+ nt_hdr_offset = coff_offset;
+ coff_offset += sizeof(struct pe32_nt_header);
+ table_offset = coff_offset;
+ coff_offset += coff_nbr_sections * sizeof(struct pe32_section_header);
+
+ /* First text sections. */
+ coff_offset = coff_align(coff_offset);
+ text_offset = coff_offset;
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ Elf_Shdr *shdr = get_shdr_by_index (i);
+ if (is_text_shdr (shdr)) {
+ /* Relocate entry. */
+ if (ehdr->e_entry >= shdr->sh_addr
+ && ehdr->e_entry < shdr->sh_addr + shdr->sh_size) {
+ coff_entry = coff_offset + ehdr->e_entry - shdr->sh_addr;
+ }
+ coff_sections_offset[i] = coff_offset;
+ coff_offset += shdr->sh_size;
+#ifdef __ia64__
+ if (coff_sections_offset[i] != shdr->sh_addr) {
+ fprintf (stderr,
+ "Section %s: Coff offset (%x) != Elf offset (%lx)",
+ shdr_str + shdr->sh_name,
+ coff_sections_offset[i],
+ shdr->sh_addr);
+ status = -1;
+ }
+#endif
+ }
+ if (shdr->sh_type == SHT_DYNAMIC) {
+ shdr_dynamic = shdr;
+ }
+ }
+#ifdef __ia64__
+ /* 16 bytes are reserved (by the ld script) for the entry point descriptor.
+ */
+ coff_entry_descr_offset = coff_offset - 16;
+#endif
+
+ coff_offset = coff_align (coff_offset);
+
+ /* Then data sections. */
+ data_offset = coff_offset;
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ Elf_Shdr *shdr = get_shdr_by_index (i);
+ if (is_data_shdr (shdr)) {
+ coff_sections_offset[i] = coff_offset;
+ coff_offset += shdr->sh_size;
+#ifdef __ia64__
+ if (coff_sections_offset[i] != shdr->sh_addr) {
+ fprintf (stderr,
+ "Section %s: Coff offset (%x) != Elf offset (%lx)",
+ shdr_str + shdr->sh_name,
+ coff_sections_offset[i],
+ shdr->sh_addr);
+ status = -1;
+ }
+#endif
+ }
+ }
+ coff_offset = coff_align (coff_offset);
+
+ reloc_offset = coff_offset;
+
+ /* Allocate base Coff file. Will be expanded later for relocations. */
+ coff_file = (uint8_t *)malloc (coff_offset);
+ memset (coff_file, 0, coff_offset);
+
+ /* Fill headers. */
+ doshdr = (struct pe32_dos_header *)coff_file;
+ doshdr->magic = 0x5A4D;
+ doshdr->new_hdr_offset = nt_hdr_offset;
+
+ nt_hdr = (struct pe32_nt_header*)(coff_file + nt_hdr_offset);
+
+ memcpy (nt_hdr->signature, "PE\0", 4);
+
+ nt_hdr->coff_header.machine = EFI_MACHINE;
+ nt_hdr->coff_header.num_sections = coff_nbr_sections;
+ nt_hdr->coff_header.time = time (NULL);
+ nt_hdr->coff_header.symtab_offset = 0;
+ nt_hdr->coff_header.num_symbols = 0;
+ nt_hdr->coff_header.optional_header_size = sizeof(nt_hdr->optional_header);
+ nt_hdr->coff_header.characteristics = PE32_EXECUTABLE_IMAGE
+ | PE32_LINE_NUMS_STRIPPED
+ | PE32_LOCAL_SYMS_STRIPPED
+ | PE32_32BIT_MACHINE;
+
+#ifdef USE_PE32
+ nt_hdr->optional_header.magic = PE32_PE32_MAGIC;
+#else
+ nt_hdr->optional_header.magic = PE32_PE64_MAGIC;
+#endif
+ nt_hdr->optional_header.code_size = data_offset - text_offset;
+ nt_hdr->optional_header.data_size = reloc_offset - data_offset;
+ nt_hdr->optional_header.bss_size = 0;
+#ifdef __ia64__
+ nt_hdr->optional_header.entry_addr = coff_entry_descr_offset;
+ coff_entry_descr_func = coff_entry;
+#else
+ nt_hdr->optional_header.entry_addr = coff_entry;
+#endif
+ nt_hdr->optional_header.code_base = text_offset;
+
+#ifdef USE_PE32
+ nt_hdr->optional_header.data_base = data_offset;
+#endif
+ nt_hdr->optional_header.image_base = 0;
+ nt_hdr->optional_header.section_alignment = coff_alignment;
+ nt_hdr->optional_header.file_alignment = coff_alignment;
+ nt_hdr->optional_header.image_size = 0;
+
+ nt_hdr->optional_header.header_size = text_offset;
+ nt_hdr->optional_header.num_data_directories = PE32_NUM_DATA_DIRECTORIES;
+
+ /* Section headers. */
+ create_section_header (".text", text_offset, data_offset - text_offset,
+ PE32_SCN_CNT_CODE
+ | PE32_SCN_MEM_EXECUTE
+ | PE32_SCN_MEM_READ);
+ create_section_header (".data", data_offset, reloc_offset - data_offset,
+ PE32_SCN_CNT_INITIALIZED_DATA
+ | PE32_SCN_MEM_WRITE
+ | PE32_SCN_MEM_READ);
+#ifdef __ia64__
+ if (shdr_dynamic != NULL)
+ {
+ Elf64_Dyn *dyn = (Elf64_Dyn*)((uint8_t*)ehdr + shdr_dynamic->sh_offset);
+ while (dyn->d_tag != DT_NULL)
+ {
+ if (dyn->d_tag == DT_PLTGOT)
+ plt_base = dyn->d_un.d_ptr;
+ dyn++;
+ }
+ }
+#endif
+ return status;
+}
+
+int
+write_sections (int (*filter)(Elf_Shdr *))
+{
+ uint32_t idx;
+ int status = 0;
+
+ /* First: copy sections. */
+ for (idx = 0; idx < ehdr->e_shnum; idx++)
+ {
+ Elf_Shdr *shdr = get_shdr_by_index (idx);
+ if ((*filter)(shdr))
+ {
+ switch (shdr->sh_type) {
+ case SHT_PROGBITS:
+ /* Copy. */
+ memcpy (coff_file + coff_sections_offset[idx],
+ (uint8_t*)ehdr + shdr->sh_offset,
+ shdr->sh_size);
+ break;
+ case SHT_NOBITS:
+ memset (coff_file + coff_sections_offset[idx], 0, shdr->sh_size);
+ break;
+ case SHT_DYNAMIC:
+ break;
+ default:
+ fprintf (stderr, "unhandled section type %x",
+ (unsigned int)shdr->sh_type);
+ status = -1;
+ }
+ }
+ }
+
+ /* Second: apply relocations. */
+ for (idx = 0; idx < ehdr->e_shnum; idx++)
+ {
+ Elf_Shdr *rel_shdr = get_shdr_by_index (idx);
+ if (rel_shdr->sh_type != SHT_REL && rel_shdr->sh_type != SHT_RELA)
+ continue;
+ Elf_Shdr *sec_shdr = get_shdr_by_index (rel_shdr->sh_info);
+ uint32_t sec_offset = coff_sections_offset[rel_shdr->sh_info];
+
+ if (rel_shdr->sh_info == 0 || (*filter)(sec_shdr))
+ {
+ uint32_t rel_idx;
+ Elf_Shdr *symtab_shdr = get_shdr_by_index(rel_shdr->sh_link);
+ uint8_t *symtab = (uint8_t*)ehdr + symtab_shdr->sh_offset;
+
+ if (rel_shdr->sh_type == SHT_REL)
+ {
+ for (rel_idx = 0;
+ rel_idx < rel_shdr->sh_size;
+ rel_idx += rel_shdr->sh_entsize)
+ {
+ Elf_Rel *rel = (Elf_Rel *)
+ ((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
+ Elf_Sym *sym = (Elf_Sym *)
+ (symtab
+ + ELF_R_SYM(rel->r_info) * symtab_shdr->sh_entsize);
+ Elf_Shdr *sym_shdr;
+ uint8_t *targ;
+
+ if (sym->st_shndx == SHN_UNDEF
+ || sym->st_shndx == SHN_ABS
+ || sym->st_shndx > ehdr->e_shnum)
+ {
+ fprintf (stderr, "bad symbol definition");
+ status = -1;
+ }
+ sym_shdr = get_shdr_by_index(sym->st_shndx);
+
+ /* Note: r_offset in a memory address.
+ Convert it to a pointer in the coff file. */
+ targ = coff_file + sec_offset
+ + (rel->r_offset - sec_shdr->sh_addr);
+
+ switch (ELF_R_TYPE(rel->r_info)) {
+ case R_386_NONE:
+ break;
+ case R_386_32:
+ /* Absolute relocation. */
+ *(uint32_t *)targ = *(uint32_t *)targ - sym_shdr->sh_addr
+ + coff_sections_offset[sym->st_shndx];
+ break;
+ case R_386_PC32:
+ /* Relative relocation: Symbol - Ip + Addend */
+ *(uint32_t *)targ = *(uint32_t *)targ
+ + (coff_sections_offset[sym->st_shndx]
+ - sym_shdr->sh_addr)
+ - (sec_offset - sec_shdr->sh_addr);
+ break;
+ default:
+ fprintf (stderr, "unhandled relocation type %lx",
+ ELF_R_TYPE(rel->r_info));
+ status = -1;
+ }
+ }
+ }
+ else if (rel_shdr->sh_type == SHT_RELA)
+ {
+ for (rel_idx = 0;
+ rel_idx < rel_shdr->sh_size;
+ rel_idx += rel_shdr->sh_entsize) {
+ Elf_Rela *rela = (Elf_Rela *)
+ ((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
+ Elf_Sym *sym = (Elf_Sym *)
+ (symtab + ELF_R_SYM(rela->r_info) * symtab_shdr->sh_entsize);
+ Elf_Shdr *sym_shdr;
+ uint8_t *targ;
+
+ if (ELF_R_TYPE(rela->r_info) == R_IA64_NONE)
+ continue;
+
+#if 0
+ if (sym->st_shndx == SHN_UNDEF
+ || sym->st_shndx == SHN_ABS
+ || sym->st_shndx > ehdr->e_shnum) {
+ fprintf (stderr, "bad symbol definition %d",
+ ELF_R_SYM(rela->r_info));
+ }
+#endif
+ sym_shdr = get_shdr_by_index (sym->st_shndx);
+
+ /* Note: r_offset in a memory address.
+ Convert it to a pointer in the coff file. */
+ targ = coff_file + sec_offset
+ + (rela->r_offset - sec_shdr->sh_addr);
+
+ switch (ELF_R_TYPE(rela->r_info)) {
+ case R_IA64_IPLTLSB:
+ /* If there is a descriptor with the same function
+ pointer as the ELF entry point, use that
+ descriptor for the PE/Coff entry. */
+ if (*(uint64_t*)targ == ehdr->e_entry) {
+ struct pe32_nt_header *nt_hdr;
+
+ nt_hdr =
+ (struct pe32_nt_header*)(coff_file + nt_hdr_offset);
+ nt_hdr->optional_header.entry_addr = targ - coff_file;
+ }
+ break;
+ case R_IA64_REL64LSB:
+ case R_IA64_NONE:
+ break;
+ default:
+ fprintf (stderr,
+ "unhandled relocation type %lx in section %d",
+ ELF_R_TYPE(rela->r_info), rel_shdr->sh_info);
+ status = -1;
+ }
+ }
+ }
+ }
+ }
+ return status;
+}
+
+void
+coff_add_fixup_entry (uint16_t val)
+{
+ *coff_entry_rel = val;
+ coff_entry_rel++;
+ coff_base_rel->block_size += 2;
+ coff_offset += 2;
+}
+
+void
+coff_add_fixup (uint32_t offset, uint8_t type)
+{
+ if (coff_base_rel == NULL
+ || coff_base_rel->page_rva != (offset & ~0xfff)) {
+ if (coff_base_rel != NULL) {
+ /* Add a null entry (is it required ?) */
+ coff_add_fixup_entry (0);
+ /* Pad for alignment. */
+ if (coff_offset % 4 != 0)
+ coff_add_fixup_entry (0);
+ }
+
+ coff_file = realloc
+ (coff_file,
+ coff_offset + sizeof(struct pe32_fixup_block) + 2*0x1000);
+ memset(coff_file + coff_offset, 0,
+ sizeof(struct pe32_fixup_block) + 2*0x1000);
+
+ coff_base_rel = (struct pe32_fixup_block*)(coff_file + coff_offset);
+ coff_base_rel->page_rva = offset & ~0xfff;
+ coff_base_rel->block_size = sizeof(struct pe32_fixup_block);
+
+ coff_entry_rel = (uint16_t *)(coff_base_rel + 1);
+ coff_offset += sizeof(struct pe32_fixup_block);
+ }
+
+ /* Fill the entry. */
+ coff_add_fixup_entry ((type << 12) | (offset & 0xfff));
+}
+
+int
+write_relocations(void)
+{
+ uint32_t idx;
+ struct pe32_nt_header *nt_hdr;
+ struct pe32_data_directory *dir;
+ int status = 0;
+
+ for (idx = 0; idx < ehdr->e_shnum; idx++)
+ {
+ Elf_Shdr *rel_shdr = get_shdr_by_index (idx);
+ if (rel_shdr->sh_type == SHT_REL)
+ {
+ Elf_Shdr *sec_shdr = get_shdr_by_index (rel_shdr->sh_info);
+ if (is_text_shdr(sec_shdr) || is_data_shdr(sec_shdr))
+ {
+ uint32_t rel_idx;
+ for (rel_idx = 0;
+ rel_idx < rel_shdr->sh_size;
+ rel_idx += rel_shdr->sh_entsize)
+ {
+ Elf_Rel *rel = (Elf_Rel *)
+ ((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
+
+ switch (ELF_R_TYPE(rel->r_info))
+ {
+ case R_386_NONE:
+ case R_386_PC32:
+ break;
+ case R_386_32:
+ coff_add_fixup(coff_sections_offset[rel_shdr->sh_info]
+ + (rel->r_offset - sec_shdr->sh_addr),
+ PE32_REL_BASED_HIGHLOW);
+ break;
+ default:
+ fprintf (stderr, "unhandled relocation type %lx",
+ ELF_R_TYPE(rel->r_info));
+ status = -1;
+ }
+ }
+ }
+ }
+ else if (rel_shdr->sh_type == SHT_RELA)
+ {
+ Elf_Shdr *sec_shdr = get_shdr_by_index(rel_shdr->sh_info);
+ if (rel_shdr->sh_info == 0
+ || is_text_shdr(sec_shdr) || is_data_shdr(sec_shdr))
+ {
+ uint32_t rel_idx;
+ for (rel_idx = 0;
+ rel_idx < rel_shdr->sh_size;
+ rel_idx += rel_shdr->sh_entsize) {
+ Elf_Rela *rela = (Elf_Rela *)
+ ((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
+ uint32_t Loc = coff_sections_offset[rel_shdr->sh_info]
+ + (rela->r_offset - sec_shdr->sh_addr);
+
+ switch (ELF_R_TYPE(rela->r_info))
+ {
+ case R_IA64_IPLTLSB:
+ coff_add_fixup(Loc, PE32_REL_BASED_DIR64);
+ coff_add_fixup(Loc + 8, PE32_REL_BASED_DIR64);
+ break;
+ case R_IA64_REL64LSB:
+ coff_add_fixup(Loc, PE32_REL_BASED_DIR64);
+ break;
+ case R_IA64_DIR64LSB:
+ coff_add_fixup(Loc, PE32_REL_BASED_DIR64);
+ break;
+ case R_IA64_IMM64:
+ coff_add_fixup(Loc, PE32_REL_BASED_IA64_IMM64);
+ break;
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL64LSB:
+ case R_IA64_SECREL32LSB:
+ case R_IA64_SEGREL64LSB:
+ break;
+ case R_IA64_GPREL22:
+ case R_IA64_LTOFF22X:
+ case R_IA64_LDXMOV:
+ case R_IA64_LTOFF_FPTR22:
+ case R_IA64_NONE:
+ break;
+ default:
+ fprintf (stderr, "unhandled relocation type %lx",
+ ELF_R_TYPE(rela->r_info));
+ status = -1;
+ }
+ }
+ }
+ }
+ }
+
+#ifdef __ia64__
+ coff_add_fixup (coff_entry_descr_offset, PE32_REL_BASED_DIR64);
+ coff_add_fixup (coff_entry_descr_offset + 8, PE32_REL_BASED_DIR64);
+#endif
+
+ /* Pad by adding empty entries. */
+ while (coff_offset & (coff_alignment - 1))
+ coff_add_fixup_entry (0);
+
+ create_section_header (".reloc", reloc_offset, coff_offset - reloc_offset,
+ PE32_SCN_CNT_INITIALIZED_DATA
+ | PE32_SCN_MEM_DISCARDABLE
+ | PE32_SCN_MEM_READ);
+
+ nt_hdr = (struct pe32_nt_header *)(coff_file + nt_hdr_offset);
+ dir = &nt_hdr->optional_header.base_relocation_table;
+ dir->rva = reloc_offset;
+ dir->size = coff_offset - reloc_offset;
+
+ return status;
+}
+
+void
+write_debug(void)
+{
+ uint32_t len = strlen(filename) + 1;
+ uint32_t debug_offset = coff_offset;
+ struct pe32_nt_header *nt_hdr;
+ struct pe32_data_directory *data_dir;
+ struct pe32_debug_directory_entry *dir;
+ struct pe32_debug_codeview_nb10_entry *nb10;
+
+ coff_offset += sizeof (struct pe32_debug_directory_entry)
+ + sizeof(struct pe32_debug_codeview_nb10_entry)
+ + len;
+ coff_offset = coff_align(coff_offset);
+
+ coff_file = realloc
+ (coff_file, coff_offset);
+ memset(coff_file + debug_offset, 0, coff_offset - debug_offset);
+
+ dir = (struct pe32_debug_directory_entry*)(coff_file + debug_offset);
+ dir->type = PE32_DEBUG_TYPE_CODEVIEW;
+ dir->data_size = sizeof(struct pe32_debug_directory_entry) + len;
+ dir->rva = debug_offset + sizeof(struct pe32_debug_directory_entry);
+ dir->file_offset = debug_offset + sizeof(struct pe32_debug_directory_entry);
+
+ nb10 = (struct pe32_debug_codeview_nb10_entry*)(dir + 1);
+ nb10->signature = PE32_CODEVIEW_SIGNATURE_NB10;
+ strcpy (nb10->filename, filename);
+
+ create_section_header (".debug", debug_offset, coff_offset - debug_offset,
+ PE32_SCN_CNT_INITIALIZED_DATA
+ | PE32_SCN_MEM_DISCARDABLE
+ | PE32_SCN_MEM_READ);
+
+ nt_hdr = (struct pe32_nt_header *)(coff_file + nt_hdr_offset);
+ data_dir = &nt_hdr->optional_header.debug;
+ data_dir->rva = debug_offset;
+ data_dir->size = coff_offset - debug_offset;
+}
+
+int
+convert_elf (uint8_t **file_buffer, unsigned int *file_length)
+{
+ struct pe32_nt_header *nt_hdr;
+
+ /* Check header, read section table. */
+ ehdr = (Elf_Ehdr*)*file_buffer;
+ if (!check_elf_header ())
+ return -1;
+
+ /* Compute sections new address. */
+ if (scan_sections () != 0)
+ return -2;
+
+ /* Write and relocate sections. */
+ if (write_sections (is_text_shdr) != 0)
+ return -3;
+
+#ifdef __ia64__
+ *(uint64_t*)(coff_file + coff_entry_descr_offset) = coff_entry_descr_func;
+ *(uint64_t*)(coff_file + coff_entry_descr_offset + 8) = plt_base;
+#endif
+
+ if (write_sections (is_data_shdr) != 0)
+ return -4;
+
+ /* Translate and write relocations. */
+ if (write_relocations () != 0)
+ return -5;
+
+ /* Write debug info. */
+ write_debug ();
+
+ nt_hdr = (struct pe32_nt_header *)(coff_file + nt_hdr_offset);
+ nt_hdr->optional_header.image_size = coff_offset;
+
+ nt_hdr->optional_header.subsystem = PE32_SUBSYSTEM_EFI_APPLICATION;
+
+ /* Replace. */
+ free (*file_buffer);
+ *file_buffer = coff_file;
+ *file_length = coff_offset;
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ FILE *f;
+ unsigned int size;
+ uint8_t *buffer;
+ const char *outfile;
+ int status;
+
+ if (argc != 3)
+ {
+ fprintf (stderr, "usage: %s elf-file pe-file\n", argv[0]);
+ exit (1);
+ }
+
+ filename = argv[1];
+ outfile = argv[2];
+ f = fopen (filename, "rb");
+ fseek (f, 0, SEEK_END);
+ size = ftell (f);
+ fseek (f, 0, SEEK_SET);
+
+ buffer = malloc (size);
+ if (buffer == NULL)
+ {
+ fprintf (stderr, "cannot allocate %u bytes of memory\n", size);
+ exit (2);
+ }
+ if (fread (buffer, size, 1, f) != 1)
+ {
+ fprintf (stderr, "cannot read %s\n", filename);
+ exit (2);
+ }
+ fclose (f);
+
+ if (!is_elf_header (buffer))
+ {
+ fprintf (stderr, "%s is not an elf file\n", filename);
+ exit (2);
+ }
+
+ status = convert_elf (&buffer, &size);
+ if (status != 0)
+ {
+ fprintf (stderr, "cannot convert %s to pe (err=%d)\n", filename, status);
+ exit (2);
+ }
+
+ f = fopen (outfile, "wb");
+ if (f == NULL)
+ {
+ fprintf (stderr, "cannot open %s\n", outfile);
+ exit (2);
+ }
+ if (fwrite (buffer, size, 1, f) != 1)
+ {
+ fprintf (stderr, "cannot write to %s\n", outfile);
+ exit (2);
+ }
+ fclose (f);
+
+ return 0;
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/util/ia64/efi/grub-install.in grub2/util/ia64/efi/grub-install.in
--- grub2.orig/util/ia64/efi/grub-install.in 1970-01-01 01:00:00.000000000 +0100
+++ grub2/util/ia64/efi/grub-install.in 2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,233 @@
+#! /bin/sh
+
+# Install GRUB on your EFI partition.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
+#
+# GRUB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GRUB. If not, see .
+
+
+# Initialize some variables.
address@hidden@
address@hidden@
address@hidden@
address@hidden@
address@hidden@
address@hidden@
address@hidden@
address@hidden@
address@hidden@
address@hidden@
address@hidden@
+pkglibdir=${libdir}/${PACKAGE_TARNAME}/${target_cpu}-${platform}
+pkgdatadir=${datadir}/${PACKAGE_TARNAME}
+
+
address@hidden@
+TARGET_CFLAGS="@TARGET_CFLAGS@"
+TARGET_CPPFLAGS="@TARGET_CPPFLAGS@"
+TARGET_LDFLAGS="@TARGET_LDFLAGS@"
address@hidden@
+
+grub_setup=${sbindir}/grub-setup
+grub_mkimage=${bindir}/grub-mkimage
+grub_mkdevicemap=${sbindir}/grub-mkdevicemap
+grub_probefs=${sbindir}/grub-probefs
+rootdir=
+grub_prefix=/boot/grub
+modules=
+
+install_device=
+recheck=no
+debug=no
+
+# Usage: usage
+# Print the usage.
+usage () {
+ cat <.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+ case "$option" in
+ -h | --help)
+ usage
+ exit 0 ;;
+ -v | --version)
+ echo "grub-install (GNU GRUB ${PACKAGE_VERSION})"
+ exit 0 ;;
+ --modules=*)
+ modules=`echo "$option" | sed 's/--modules=//'` ;;
+ --root-directory=*)
+ rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+ --grub-setup=*)
+ grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;;
+ --grub-mkimage=*)
+ grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
+ --grub-mkdevicemap=*)
+ grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
+ --grub-probefs=*)
+ grub_probefs=`echo "$option" | sed 's/--grub-probefs=//'` ;;
+ --pkglibdir=*)
+ pkglibdir=`echo "$option" | sed 's/--pkglibdir=//'` ;;
+ --pkgdatadir=*)
+ pkgdatadir=`echo "$option" | sed 's/--pkgdatadir=//'` ;;
+ --recheck)
+ recheck=yes ;;
+ # This is an undocumented feature...
+ --debug)
+ debug=yes ;;
+ -*)
+ echo "Unrecognized option \`$option'" 1>&2
+ usage
+ exit 1
+ ;;
+ *)
+ if test "x$install_device" != x; then
+ echo "More than one install_devices?" 1>&2
+ usage
+ exit 1
+ fi
+ install_device="${option}" ;;
+ esac
+done
+
+#if test "x$install_device" = x; then
+# echo "install_device not specified." 1>&2
+# usage
+# exit 1
+#fi
+
+# If the debugging feature is enabled, print commands.
+if test $debug = yes; then
+ set -x
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+bootdir=${rootdir}/boot/efi
+
+grubdir=${bootdir}/grub
+device_map=${grubdir}/device.map
+
+# Create the GRUB directory if it is not present.
+test -d "$bootdir" || mkdir "$bootdir" || exit 1
+test -d "$grubdir" || mkdir "$grubdir" || exit 1
+
+# Copy the GRUB images to the GRUB directory.
+if false; then
+ for file in ${grubdir}/*.mod ${grubdir}/*.lst; do
+ if test -f $file; then
+ rm -f $file || exit 1
+ fi
+ done
+ for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do
+ cp -f $file ${grubdir} || exit 1
+ done
+fi
+
+# Create the core image. First, auto-detect the filesystme module.
+#fs_module=`$grub_probefs --device-map=${device_map} ${grubdir}`
+#if test "x$fs_module" = x -a "x$modules" = x; then
+# echo "Auto-detection of a filesystem module failed." 1>&2
+# echo "Please specify the module with the option \`--modules' explicitly." 1>&2
+# exit 1
+#fi
+
+# Typically, _chain and pc are required.
+modules="$modules $fs_module _chain"
+
+modules="kernel gzio gpt fat normal ls cat fshelp help _linux linux $modules"
+modules="$modules memmap systab boot"
+
+if [ $debug = yes ]; then
+ tmpdir=.
+else
+ tmpdir=`mktemp -d /tmp/grub.XXXXXXXXXX` || exit 1
+ trap "rm -rf $tmpdir" 1 2 13 15
+fi
+
+# Generate init/fini for modules.
+modfile=$tmpdir/mod.c
+echo "/* Dummy modules. */" > $modfile
+list=""
+init_list=""
+fini_list=""
+for m in $modules; do
+ file="$pkglibdir/${m}.mod"
+ name=`nm $file | sed -n "/ r grub_module_name/ s/.* r grub_module_name_\(.*\)/\1/p"`
+ init=`nm $file | sed -n "/ T grub_module_.*_init/ s/.* T //p"`
+ fini=`nm $file | sed -n "/ T grub_module_.*_fini/ s/.* T //p"`
+ init_list="$init_list $init"
+ fini_list="$fini_list $fini"
+ arg="\"$name\",${init:-0},${fini:-0}"
+ list="$list $arg"
+done
+echo "extern void grub_init_module (const char *, void (*init)(void *), void (*fini)(void));" >> $modfile
+echo "extern void grub_init_modules (void);" >> $modfile
+for m in $init_list; do
+ echo "extern void $m(void *);" >> $modfile
+done
+for m in $fini_list; do
+ echo "extern void $m(void);" >> $modfile
+done
+echo "void grub_init_modules (void)" >> $modfile
+echo "{" >> $modfile
+for m in $list; do
+ echo " grub_init_module($m);" >> $modfile
+done
+echo "}" >> $modfile
+
+$TARGET_CC -c $TARGET_CFLAGS -o $tmpdir/mod.o $modfile
+
+mod_objs=
+for m in $modules; do mod_objs="$mod_objs $pkglibdir/${m}.mod"; done
+
+ld -pie -nostdlib -T $pkgdatadir/elf_ia64_efi.lds \
+ $mod_objs $tmpdir/mod.o -o $tmpdir/grub.elf
+
+
+if ! $bindir/grub-elf2pe $tmpdir/grub.elf $grubdir/grub.efi; then
+ echo "Failed to build efi binary"
+ [ $debug = no ] && rm -rf $tmpdir
+ exit 1
+fi
+
+echo "grub.efi generated"
+
+[ $debug = no ] && rm -rf $tmpdir
+
+# Bye.
+exit 0
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/util/ia64/efi/pe32.h grub2/util/ia64/efi/pe32.h
--- grub2.orig/util/ia64/efi/pe32.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2/util/ia64/efi/pe32.h 2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,237 @@
+/* pe32.h - PE/Coff definitions. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+#ifdef USE_PE32PLUS
+typedef uint64_t pe32_uintptr_t;
+#else
+typedef uint32_t pe32_uintptr_t;
+#endif
+
+struct pe32_coff_header
+{
+ uint16_t machine;
+ uint16_t num_sections;
+ uint32_t time;
+ uint32_t symtab_offset;
+ uint32_t num_symbols;
+ uint16_t optional_header_size;
+ uint16_t characteristics;
+};
+
+#define PE32_MACHINE_I386 0x014c
+#define PE32_MACHINE_IA64 0x0200
+#define PE32_MACHINE_EBC 0x0EBC
+#define PE32_MACHINE_X64 0x8664
+
+#define PE32_RELOCS_STRIPPED 0x0001
+#define PE32_EXECUTABLE_IMAGE 0x0002
+#define PE32_LINE_NUMS_STRIPPED 0x0004
+#define PE32_LOCAL_SYMS_STRIPPED 0x0008
+#define PE32_AGGRESSIVE_WS_TRIM 0x0010
+#define PE32_LARGE_ADDRESS_AWARE 0x0020
+#define PE32_16BIT_MACHINE 0x0040
+#define PE32_BYTES_REVERSED_LO 0x0080
+#define PE32_32BIT_MACHINE 0x0100
+#define PE32_DEBUG_STRIPPED 0x0200
+#define PE32_REMOVABLE_RUN_FROM_SWAP 0x0400
+#define PE32_SYSTEM 0x1000
+#define PE32_DLL 0x2000
+#define PE32_UP_SYSTEM_ONLY 0x4000
+#define PE32_BYTES_REVERSED_HI 0x8000
+
+struct pe32_data_directory
+{
+ uint32_t rva;
+ uint32_t size;
+};
+
+struct pe32_optional_header
+{
+ uint16_t magic;
+ uint8_t major_linker_version;
+ uint8_t minor_linker_version;
+ uint32_t code_size;
+ uint32_t data_size;
+ uint32_t bss_size;
+ uint32_t entry_addr;
+ uint32_t code_base;
+
+#ifndef USE_PE32PLUS
+ uint32_t data_base;
+#endif
+
+ pe32_uintptr_t image_base;
+ uint32_t section_alignment;
+ uint32_t file_alignment;
+ uint16_t major_os_version;
+ uint16_t minor_os_version;
+ uint16_t major_image_version;
+ uint16_t minor_image_version;
+ uint16_t major_subsystem_version;
+ uint16_t minor_subsystem_version;
+ uint32_t reserved;
+ uint32_t image_size;
+ uint32_t header_size;
+ uint32_t checksum;
+ uint16_t subsystem;
+ uint16_t dll_characteristics;
+ pe32_uintptr_t stack_reserve_size;
+ pe32_uintptr_t stack_commit_size;
+ pe32_uintptr_t heap_reserve_size;
+ pe32_uintptr_t heap_commit_size;
+ uint32_t loader_flags;
+ uint32_t num_data_directories;
+
+ /* Data directories. */
+ struct pe32_data_directory export_table;
+ struct pe32_data_directory import_table;
+ struct pe32_data_directory resource_table;
+ struct pe32_data_directory exception_table;
+ struct pe32_data_directory certificate_table;
+ struct pe32_data_directory base_relocation_table;
+ struct pe32_data_directory debug;
+ struct pe32_data_directory architecture;
+ struct pe32_data_directory global_ptr;
+ struct pe32_data_directory tls_table;
+ struct pe32_data_directory load_config_table;
+ struct pe32_data_directory bound_import;
+ struct pe32_data_directory iat;
+ struct pe32_data_directory delay_import_descriptor;
+ struct pe32_data_directory com_runtime_header;
+ struct pe32_data_directory reserved_entry;
+};
+
+#define PE32_PE32_MAGIC 0x10b
+#define PE32_PE64_MAGIC 0x20b
+
+#define PE32_SUBSYSTEM_EFI_APPLICATION 10
+#define PE32_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define PE32_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+#define PE32_SUBSYSTEM_EFI_EFI_ROM 13
+
+#define PE32_NUM_DATA_DIRECTORIES 16
+
+struct pe32_section_header
+{
+ char name[8];
+ uint32_t virtual_size;
+ uint32_t virtual_address;
+ uint32_t raw_data_size;
+ uint32_t raw_data_offset;
+ uint32_t relocations_offset;
+ uint32_t line_numbers_offset;
+ uint16_t num_relocations;
+ uint16_t num_line_numbers;
+ uint32_t characteristics;
+};
+
+#define PE32_SCN_CNT_CODE 0x00000020
+#define PE32_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define PE32_SCN_MEM_DISCARDABLE 0x02000000
+#define PE32_SCN_MEM_EXECUTE 0x20000000
+#define PE32_SCN_MEM_READ 0x40000000
+#define PE32_SCN_MEM_WRITE 0x80000000
+
+struct pe32_dos_header
+{
+ uint16_t magic; // Magic number
+ uint16_t cblp; // Bytes on last page of file
+ uint16_t cp; // Pages in file
+ uint16_t crlc; // Relocations
+ uint16_t cparhdr; // Size of header in paragraphs
+ uint16_t minalloc; // Minimum extra paragraphs needed
+ uint16_t maxalloc; // Maximum extra paragraphs needed
+ uint16_t ss; // Initial (relative) SS value
+ uint16_t sp; // Initial SP value
+ uint16_t csum; // Checksum
+ uint16_t ip; // Initial IP value
+ uint16_t cs; // Initial (relative) CS value
+ uint16_t lfa_rlc; // File address of relocation table
+ uint16_t ov_no; // Overlay number
+ uint16_t res[4]; // Reserved words
+ uint16_t oem_id; // OEM identifier (for e_oeminfo)
+ uint16_t oem_info; // OEM information; e_oemid specific
+ uint16_t res2[10]; // Reserved words
+ uint32_t new_hdr_offset;
+
+ uint16_t stub[0x20];
+};
+
+struct pe32_nt_header
+{
+ /* This is always PE\0\0. */
+ char signature[4];
+
+ /* The COFF file header. */
+ struct pe32_coff_header coff_header;
+
+ /* The Optional header. */
+ struct pe32_optional_header optional_header;
+};
+
+struct pe32_base_relocation
+{
+ uint32_t page_rva;
+ uint32_t block_size;
+};
+
+struct pe32_fixup_block
+{
+ uint32_t page_rva;
+ uint32_t block_size;
+ uint16_t entries[0];
+};
+
+#define PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset))
+
+#define PE32_REL_BASED_ABSOLUTE 0
+#define PE32_REL_BASED_HIGHLOW 3
+#define PE32_REL_BASED_IA64_IMM64 9
+#define PE32_REL_BASED_DIR64 10
+
+#define PE32_DEBUG_TYPE_CODEVIEW 2
+struct pe32_debug_directory_entry {
+ uint32_t characteristics;
+ uint32_t time;
+ uint16_t major_version;
+ uint16_t minor_version;
+ uint32_t type;
+ uint32_t data_size;
+ uint32_t rva;
+ uint32_t file_offset;
+};
+
+#define PE32_CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10"
+struct pe32_debug_codeview_nb10_entry {
+ uint32_t signature; // "NB10"
+ uint32_t unknown[3];
+ char filename[0]; /* Filename of .PDB */
+};
+
+
+#if 1
+#define pe32_check(name, x) extern char pe32_check_##name [x ? 1 : -1]
+#ifdef USE_PE32PLUS
+#define PE32_HEADER_SIZE 112
+#else
+#define PE32_HEADER_SIZE 96
+#endif
+
+pe32_check(optional_header, sizeof (struct pe32_optional_header) == PE32_HEADER_SIZE + PE32_NUM_DATA_DIRECTORIES * 8);
+#endif
+