* IA64 port
@ 2008-01-28 16:09 Tristan Gingold
2008-01-28 16:55 ` Robert Millan
0 siblings, 1 reply; 43+ messages in thread
From: Tristan Gingold @ 2008-01-28 16:09 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 1117 bytes --]
Hi,
here is the patch to add support for ia64. This is mostly new files
(as well as new commands used to debug), and a few fixes in kern/efi/mm.c and
fs/fat.c.
Ia64 uses EFI so this port leverage on the already existing EFI support.
This port deviate from other grub ports in modules: I currently use a trick
to provide basic module support: they are prelinked during installation.
This makes the initial port easier (and possible other ports too).
I'd really like to improve the situation in the next future, but the current
module framework doesn't work as-is for ia64. Loading partially linked object
files (-r) is not easy on ia64 (large number of relocations, new segments
to be added: the GOT, the function descriptors). I will try to use shared
libraries instead but there are changes to do in the generic code.
On the other hand, having pre-linked modules is a nice alternative on EFI
systems where the on-demand module load feature is not required and doesn't
fit well in net booting process. So maybe I will first try to make to
improve this feature.
Comments are of course well-come.
Tristan.
[-- Attachment #2: grub.diffs --]
[-- Type: text/plain, Size: 129811 bytes --]
2008-01-28 Tristan Gingold <gingold@free.fr>
* geninit.sh: Call _init with a null argument.
* configure.ac: Add ia64-efi target.
* Makefile.in (STRIP_FLAGS): Declare (overriden on ia64).
(RMKFILES): Add ia64-efi.rmk
* 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/rescue.c: Silently accept empty lines.
* 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 grub2.orig/Makefile.in grub2/Makefile.in
--- grub2.orig/Makefile.in 2008-01-08 11:00:42.000000000 +0100
+++ grub2/Makefile.in 2008-01-28 16:29:58.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@
@@ -83,7 +84,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)
+ sparc64-ieee1275.rmk i386-efi.rmk ia64-efi.rmk)
MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES))
PKGLIB = $(pkglib_IMAGES) $(pkglib_MODULES) $(pkglib_PROGRAMS) \
diff -ruNp -x '*~' -x CVS 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-28 16:29:57.000000000 +0100
@@ -0,0 +1,193 @@
+/* acpi.c - Display acpi. */
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+
+static grub_uint32_t read16 (grub_uint8_t *p)
+{
+ return p[0] | (p[1] << 8);
+}
+
+static grub_uint32_t read32 (grub_uint8_t *p)
+{
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+static grub_uint64_t read64 (grub_uint8_t *p)
+{
+ grub_uint32_t l, h;
+ l = read32(p);
+ h = read32(p + 4);
+ return l | (((grub_uint64_t)h) << 32);
+}
+
+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 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 <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#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 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 <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#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 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-28 16:29:57.000000000 +0100
@@ -0,0 +1,122 @@
+# -*- 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
+
+# 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/ext2.c fs/fat.c fs/fshelp.c fs/hfs.c fs/iso9660.c \
+ fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c fs/hfsplus.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 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 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 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 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}
#{@name}: #{pre_obj} #{mod_obj}
-rm -f $@
$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
- $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+ $(STRIP) $(STRIP_FLAGS) $@
#{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str}
-rm -f $@
diff -ruNp -x '*~' -x CVS 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 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 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-28 16:29:57.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2003,2007 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 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 <http://www.gnu.org/licenses/>.
+ */
+
+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 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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef GRUB_MACHINE_TIME_HEADER
+#define GRUB_MACHINE_TIME_HEADER 1
+
+#include <grub/efi/time.h>
+
+#endif /* ! GRUB_MACHINE_TIME_HEADER */
diff -ruNp -x '*~' -x CVS 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-28 16:29:57.000000000 +0100
@@ -0,0 +1,31 @@
+/* Define the machine-dependent type `jmp_buf'. Linux/IA-64 version.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ 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 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-28 16:29:57.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2007 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 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 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 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 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 <grub/efi/api.h>
#include <grub/efi/efi.h>
+//#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 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 <http://www.gnu.org/licenses/>.
+ */
+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 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/cache.h>
+#include <grub/kernel.h>
+#include <grub/efi/efi.h>
+
+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 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 <http://www.gnu.org/licenses/>.
+ */
+ .text
+ .psr abi64
+ .psr lsb
+ .lsb
+
+ .global _start
+ .proc _start
+_start:
+ alloc loc0=ar.pfs,2,4,0,0
+ mov loc1=rp
+ addl loc2=@gprel(grub_efi_image_handle),gp
+ addl loc3=@gprel(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 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-28 16:29:58.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 <http://www.gnu.org/licenses/>.
+ */
+ .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 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)
{
if (n == 0)
diff -ruNp -x '*~' -x CVS grub2.orig/kern/rescue.c grub2/kern/rescue.c
--- grub2.orig/kern/rescue.c 2007-09-03 22:28:23.000000000 +0200
+++ grub2/kern/rescue.c 2008-01-28 16:29:58.000000000 +0100
@@ -659,6 +659,8 @@ grub_enter_rescue_mode (void)
/* Get a command line. */
grub_rescue_get_command_line ("grub rescue> ");
+ if (line[0] == 0)
+ continue;
if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0)
continue;
diff -ruNp -x '*~' -x CVS 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-28 16:29:58.000000000 +0100
@@ -0,0 +1,776 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/rescue.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/cache.h>
+/* #include <grub/cpu/linux.h> */
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/elf.h>
+#include <grub/gzio.h>
+
+#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 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-28 16:29:58.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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/loader.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+
+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 ("normal");
+ grub_unregister_command ("relocate");
+ grub_unregister_command ("fpswa");
+}
diff -ruNp -x '*~' -x CVS 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-28 16:29:58.000000000 +0100
@@ -0,0 +1,162 @@
+/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ 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 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-28 16:29:58.000000000 +0100
@@ -0,0 +1,171 @@
+/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ 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 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-28 16:29:58.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 <http://www.gnu.org/licenses/>.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <elf.h>
+
+#if defined(i386)
+#define USE_ELF32
+#define USE_PE32
+#define ELF_MACHINE EM_386
+#define EFI_MACHINE PE32_MACHINE_I386
+#elif defined(__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 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 <http://www.gnu.org/licenses/>.
+
+
+# Initialize some variables.
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libdir=@libdir@
+datadir=@datadir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/${PACKAGE_TARNAME}/${target_cpu}-${platform}
+pkgdatadir=${datadir}/${PACKAGE_TARNAME}
+
+
+TARGET_CC=@TARGET_CC@
+TARGET_CFLAGS="@TARGET_CFLAGS@"
+TARGET_CPPFLAGS="@TARGET_CPPFLAGS@"
+TARGET_LDFLAGS="@TARGET_LDFLAGS@"
+OBJCOPY=@OBJCOPY@
+
+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
+Usage: grub-install [OPTION] install_device
+Install GRUB on your drive.
+
+ -h, --help print this message and exit
+ -v, --version print the version information and exit
+ --modules=MODULES pre-load specified modules MODULES
+ --root-directory=DIR install GRUB images under the directory DIR
+ instead of the root directory
+ --grub-setup=FILE use FILE as grub-setup
+ --grub-mkimage=FILE use FILE as grub-mkimage
+ --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
+ --grub-probefs=FILE use FILE as grub-probefs
+ --no-floppy do not probe any floppy drive
+ --recheck probe a device map even if it already exists
+
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+
+grub-install copies GRUB images into the DIR/boot directory specfied by
+--root-directory, and uses grub-setup to install grub into the boot
+sector.
+
+Report bugs to <bug-grub@gnu.org>.
+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 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 <http://www.gnu.org/licenses/>.
+ */
+#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
+
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-28 16:09 IA64 port Tristan Gingold
@ 2008-01-28 16:55 ` Robert Millan
2008-01-29 5:12 ` Tristan Gingold
2008-01-29 5:49 ` Tristan Gingold
0 siblings, 2 replies; 43+ messages in thread
From: Robert Millan @ 2008-01-28 16:55 UTC (permalink / raw)
To: The development of GRUB 2
Hi Tristan!
On Mon, Jan 28, 2008 at 05:09:05PM +0100, Tristan Gingold wrote:
> Hi,
>
> here is the patch to add support for ia64. This is mostly new files
> (as well as new commands used to debug), and a few fixes in kern/efi/mm.c and
> fs/fat.c.
>
> Ia64 uses EFI so this port leverage on the already existing EFI support.
>
> This port deviate from other grub ports in modules: I currently use a trick
> to provide basic module support: they are prelinked during installation.
> This makes the initial port easier (and possible other ports too).
Have you checked if this trick works on other ports? Maybe it'd be a good idea
to merge this first.
> +STRIP_FLAGS=--strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment
Why this? I recall strip was already run with those parameters.
> RMKFILES = $(addprefix conf/,common.rmk i386-pc.rmk powerpc-ieee1275.rmk \
> - sparc64-ieee1275.rmk i386-efi.rmk)
> + sparc64-ieee1275.rmk i386-efi.rmk ia64-efi.rmk)
Oops, the two last ports I added are missing here. I wonder if there's any way
to automate this part. conf/*.rmk ?
> +static grub_uint32_t read16 (grub_uint8_t *p)
> +{
> + return p[0] | (p[1] << 8);
> +}
> +
> +static grub_uint32_t read32 (grub_uint8_t *p)
> +{
> + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
> +}
> +
> +static grub_uint64_t read64 (grub_uint8_t *p)
> +{
> + grub_uint32_t l, h;
> + l = read32(p);
> + h = read32(p + 4);
> + return l | (((grub_uint64_t)h) << 32);
> +}
You could use the endian conversion macros from grub/types.h
> +# 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/ext2.c fs/fat.c fs/fshelp.c fs/hfs.c fs/iso9660.c \
> + fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c fs/hfsplus.c \
Please could you resync the filesystem chunk to have the (recently changed)
same layout as the other ports? This will ease maintainance and prevent
future mistakes.
> +# 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)
Does this work on i386-efi ?
> diff -ruNp -x '*~' -x CVS 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);
Why is this needed? I'm not sure if it's good to exploit this "unreliability"
feature that fat provides us ;-)
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2002,2003,2007 Free Software Foundation, Inc.
Please remember to update copyright years (in new or modified files).
> +__ia64_trampoline:
> + // Read address of the real descriptor
I think the consensus is to use /**/ comments in GRUB.
> diff -ruNp -x '*~' -x CVS grub2.orig/kern/rescue.c grub2/kern/rescue.c
> --- grub2.orig/kern/rescue.c 2007-09-03 22:28:23.000000000 +0200
> +++ grub2/kern/rescue.c 2008-01-28 16:29:58.000000000 +0100
> @@ -659,6 +659,8 @@ grub_enter_rescue_mode (void)
>
> /* Get a command line. */
> grub_rescue_get_command_line ("grub rescue> ");
> + if (line[0] == 0)
> + continue;
Great! Finally somebody found that annoying bug ;-)
> +struct ia64_boot_param {
Please add a newline before opening brackets.
> +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);
Multiboot module loader in linux_normal.mod ?
Btw, this command is not unregistered.
> diff -ruNp -x '*~' -x CVS 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-28 16:29:58.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 <http://www.gnu.org/licenses/>.
> + */
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <time.h>
> +#include <elf.h>
> +
> +#if defined(i386)
> +#define USE_ELF32
> +#define USE_PE32
> +#define ELF_MACHINE EM_386
> +#define EFI_MACHINE PE32_MACHINE_I386
> +#elif defined(__ia64__)
> +#define USE_ELF64
> +#define USE_PE32PLUS
> +#define ELF_MACHINE EM_IA_64
> +#define EFI_MACHINE PE32_MACHINE_IA64
> +#else
> +#error "unknown architecture"
> +#endif
This utility seems to be usable on i386 too? In that case, better to put it
outside ia64/ dir?
> --- 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
(same here, I assume)
> diff -ruNp -x '*~' -x CVS 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
Any ia64-isms here, or just improvements (the module hack you described?)
that could be shared with i386/efi/grub-install.in ?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-28 16:55 ` Robert Millan
@ 2008-01-29 5:12 ` Tristan Gingold
2008-01-29 9:17 ` Robert Millan
2008-01-29 9:59 ` Robert Millan
2008-01-29 5:49 ` Tristan Gingold
1 sibling, 2 replies; 43+ messages in thread
From: Tristan Gingold @ 2008-01-29 5:12 UTC (permalink / raw)
To: The development of GRUB 2
On Mon, Jan 28, 2008 at 05:55:04PM +0100, Robert Millan wrote:
>
> Hi Tristan!
[...]
> > This port deviate from other grub ports in modules: I currently use a trick
> > to provide basic module support: they are prelinked during installation.
> > This makes the initial port easier (and possible other ports too).
>
> Have you checked if this trick works on other ports? Maybe it'd be a good idea
> to merge this first.
I don't really understand what do you mean by 'works on other ports'. It is
designed to be an optionnal feature used only by ia64. Nothing IA64 specific
and other ports may use it. If we go this way, it would be good to slightly
improve it.
> > +STRIP_FLAGS=--strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment
>
> Why this? I recall strip was already run with those parameters.
This is the default value, overriden by ia64. Maybe each port should define
it but I'd prefer not to touch other port (as I can't test all of them).
> > RMKFILES = $(addprefix conf/,common.rmk i386-pc.rmk powerpc-ieee1275.rmk \
> > - sparc64-ieee1275.rmk i386-efi.rmk)
> > + sparc64-ieee1275.rmk i386-efi.rmk ia64-efi.rmk)
>
> Oops, the two last ports I added are missing here. I wonder if there's any way
> to automate this part. conf/*.rmk ?
Ok for *.rmk.
> > +static grub_uint32_t read16 (grub_uint8_t *p)
> > +{
> > + return p[0] | (p[1] << 8);
> > +}
> > +
> > +static grub_uint32_t read32 (grub_uint8_t *p)
> > +{
> > + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
> > +}
> > +
> > +static grub_uint64_t read64 (grub_uint8_t *p)
> > +{
> > + grub_uint32_t l, h;
> > + l = read32(p);
> > + h = read32(p + 4);
> > + return l | (((grub_uint64_t)h) << 32);
> > +}
>
> You could use the endian conversion macros from grub/types.h
Ok.
> > +# 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/ext2.c fs/fat.c fs/fshelp.c fs/hfs.c fs/iso9660.c \
> > + fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c fs/hfsplus.c \
>
> Please could you resync the filesystem chunk to have the (recently changed)
> same layout as the other ports? This will ease maintainance and prevent
> future mistakes.
Ok.
> > +# 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)
>
> Does this work on i386-efi ?
Nothing IA64 specific and useless there are bugs it should work as is on
i386-efi. That's mostly debug commands, not that useful.
> > diff -ruNp -x '*~' -x CVS 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);
>
> Why is this needed? I'm not sure if it's good to exploit this "unreliability"
> feature that fat provides us ;-)
On EFI, the prefix is extracted from an EFI path, whose case may not match
the FAT entries. Without case insensitive comparaison, grub may not find
the prefix and thus refuses to go to normal mode. Quiet boring and not easy
to understand for a beginner.
> > + * GRUB -- GRand Unified Bootloader
> > + * Copyright (C) 2002,2003,2007 Free Software Foundation, Inc.
>
> Please remember to update copyright years (in new or modified files).
Ok.
> > +__ia64_trampoline:
> > + // Read address of the real descriptor
>
> I think the consensus is to use /**/ comments in GRUB.
Ok.
> > diff -ruNp -x '*~' -x CVS grub2.orig/kern/rescue.c grub2/kern/rescue.c
> > --- grub2.orig/kern/rescue.c 2007-09-03 22:28:23.000000000 +0200
> > +++ grub2/kern/rescue.c 2008-01-28 16:29:58.000000000 +0100
> > @@ -659,6 +659,8 @@ grub_enter_rescue_mode (void)
> >
> > /* Get a command line. */
> > grub_rescue_get_command_line ("grub rescue> ");
> > + if (line[0] == 0)
> > + continue;
>
> Great! Finally somebody found that annoying bug ;-)
I can make a separate patch for this one, if you prefer.
> > +struct ia64_boot_param {
>
> Please add a newline before opening brackets.
Ok.
> > +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);
>
> Multiboot module loader in linux_normal.mod ?
Well, well well. Long question :-)
Ia64 doesn't really fit in multiboot: it's a full 64 bits processor, there
may be no room for an header in the 8KB (or you have to waste a lot of memory
to keep alignment), no room for EFI pointers in the header and no Ia64 OS
uses it. Well this were my conclusion when I read MB specs.
On the other hand I really need to have modules for Xen.
> Btw, this command is not unregistered.
Ok.
> > diff -ruNp -x '*~' -x CVS 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-28 16:29:58.000000000 +0100
[...]
>
> This utility seems to be usable on i386 too? In that case, better to put it
> outside ia64/ dir?
It should work on i386 too, but not tested.
I have written this utility for my port of EFI and adapted the style for
grub. It may be nice to share this code with i386 but not really required
now IMHO.
> > diff -ruNp -x '*~' -x CVS 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
>
> Any ia64-isms here, or just improvements (the module hack you described?)
> that could be shared with i386/efi/grub-install.in ?
Yes, the module hack makes ia64/grub-install.in very different from the
i386 one.
Tristan.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-28 16:55 ` Robert Millan
2008-01-29 5:12 ` Tristan Gingold
@ 2008-01-29 5:49 ` Tristan Gingold
2008-01-29 9:08 ` Robert Millan
2008-01-29 13:36 ` Robert Millan
1 sibling, 2 replies; 43+ messages in thread
From: Tristan Gingold @ 2008-01-29 5:49 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 224 bytes --]
Hi,
here is my new version of the patch. I think all the comments have been
addressed.
(There are still // comments in the .S files I copied from glibc. I suppose
this is OK as the files come as-is from glibc).
Tristan.
[-- Attachment #2: grub.diffs2 --]
[-- Type: text/plain, Size: 132010 bytes --]
2008-01-28 Tristan Gingold <gingold@free.fr>
* 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 <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+
+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 <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#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}
#{@name}: #{pre_obj} #{mod_obj}
-rm -f $@
$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
- $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+ $(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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef GRUB_MACHINE_TIME_HEADER
+#define GRUB_MACHINE_TIME_HEADER 1
+
+#include <grub/efi/time.h>
+
+#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 <davidm@hpl.hp.com>.
+
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 <grub/efi/api.h>
#include <grub/efi/efi.h>
+//#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 <http://www.gnu.org/licenses/>.
+ */
+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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/cache.h>
+#include <grub/kernel.h>
+#include <grub/efi/efi.h>
+
+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 <http://www.gnu.org/licenses/>.
+ */
+ .text
+ .psr abi64
+ .psr lsb
+ .lsb
+
+ .global _start
+ .proc _start
+_start:
+ alloc loc0=ar.pfs,2,4,0,0
+ mov loc1=rp
+ addl loc2=@gprel(grub_efi_image_handle),gp
+ addl loc3=@gprel(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 <http://www.gnu.org/licenses/>.
+ */
+ .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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/rescue.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/cache.h>
+/* #include <grub/cpu/linux.h> */
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/elf.h>
+#include <grub/gzio.h>
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/loader.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+
+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 <davidm@hpl.hp.com>.
+
+ 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 <davidm@hpl.hp.com>.
+
+ 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 <http://www.gnu.org/licenses/>.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <elf.h>
+
+#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 <http://www.gnu.org/licenses/>.
+
+
+# Initialize some variables.
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libdir=@libdir@
+datadir=@datadir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/${PACKAGE_TARNAME}/${target_cpu}-${platform}
+pkgdatadir=${datadir}/${PACKAGE_TARNAME}
+
+
+TARGET_CC=@TARGET_CC@
+TARGET_CFLAGS="@TARGET_CFLAGS@"
+TARGET_CPPFLAGS="@TARGET_CPPFLAGS@"
+TARGET_LDFLAGS="@TARGET_LDFLAGS@"
+OBJCOPY=@OBJCOPY@
+
+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
+Usage: grub-install [OPTION] install_device
+Install GRUB on your drive.
+
+ -h, --help print this message and exit
+ -v, --version print the version information and exit
+ --modules=MODULES pre-load specified modules MODULES
+ --root-directory=DIR install GRUB images under the directory DIR
+ instead of the root directory
+ --grub-setup=FILE use FILE as grub-setup
+ --grub-mkimage=FILE use FILE as grub-mkimage
+ --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
+ --grub-probefs=FILE use FILE as grub-probefs
+ --no-floppy do not probe any floppy drive
+ --recheck probe a device map even if it already exists
+
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+
+grub-install copies GRUB images into the DIR/boot directory specfied by
+--root-directory, and uses grub-setup to install grub into the boot
+sector.
+
+Report bugs to <bug-grub@gnu.org>.
+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 <http://www.gnu.org/licenses/>.
+ */
+#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
+
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 5:49 ` Tristan Gingold
@ 2008-01-29 9:08 ` Robert Millan
2008-01-29 10:10 ` tgingold
2008-01-29 13:36 ` Robert Millan
1 sibling, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-01-29 9:08 UTC (permalink / raw)
To: The development of GRUB 2
On Tue, Jan 29, 2008 at 06:49:31AM +0100, Tristan Gingold wrote:
> -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
Don't these two break srcdir != objdir builds?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 5:12 ` Tristan Gingold
@ 2008-01-29 9:17 ` Robert Millan
2008-01-29 10:31 ` tgingold
2008-01-29 9:59 ` Robert Millan
1 sibling, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-01-29 9:17 UTC (permalink / raw)
To: The development of GRUB 2
On Tue, Jan 29, 2008 at 06:12:52AM +0100, Tristan Gingold wrote:
> > Have you checked if this trick works on other ports? Maybe it'd be a good idea
> > to merge this first.
>
> I don't really understand what do you mean by 'works on other ports'. It is
> designed to be an optionnal feature used only by ia64. Nothing IA64 specific
> and other ports may use it. If we go this way, it would be good to slightly
> improve it.
I suggest you just make sure it'll be usable on other ports in case a need
arises, without going out of your way to support it.
> > > +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);
> >
> > Multiboot module loader in linux_normal.mod ?
>
> Well, well well. Long question :-)
>
> Ia64 doesn't really fit in multiboot: it's a full 64 bits processor,
But there's multiboot2.
> there
> may be no room for an header in the 8KB (or you have to waste a lot of memory
> to keep alignment), no room for EFI pointers in the header and no Ia64 OS
> uses it. Well this were my conclusion when I read MB specs.
Does this affect only EFI, or ia64 in general (e.g. ia64-coreboot, when that
exists) ?
Also note the string "Load a Multiboot module." is present.
If this is not multiboot, I'd suggest renaming the command to avoid name
collisions (not only if multiboot is added later, but also user confusion).
> > > diff -ruNp -x '*~' -x CVS 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-28 16:29:58.000000000 +0100
> [...]
> >
> > This utility seems to be usable on i386 too? In that case, better to put it
> > outside ia64/ dir?
>
> It should work on i386 too, but not tested.
> I have written this utility for my port of EFI and adapted the style for
> grub. It may be nice to share this code with i386 but not really required
> now IMHO.
util/i386/efi/grub-mkimage.c already generates PE, right? Why a different
way to handle this? Sound like it'd be more consistent to either use elf2pe
on both or share the same grub-mkimage. What do you think?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 5:12 ` Tristan Gingold
2008-01-29 9:17 ` Robert Millan
@ 2008-01-29 9:59 ` Robert Millan
2008-01-29 10:35 ` tgingold
2008-02-05 22:49 ` Alexandre Boeglin
1 sibling, 2 replies; 43+ messages in thread
From: Robert Millan @ 2008-01-29 9:59 UTC (permalink / raw)
To: The development of GRUB 2
On Tue, Jan 29, 2008 at 06:12:52AM +0100, Tristan Gingold wrote:
> > > --- 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);
> >
> > Why is this needed? I'm not sure if it's good to exploit this "unreliability"
> > feature that fat provides us ;-)
>
> On EFI, the prefix is extracted from an EFI path, whose case may not match
> the FAT entries.
Can you be more specific about this? What do the specs say? We wrote
/boot/grub ourselves via grub-install; is an EFI-compliant firmware
allowed to actively mess up case in paths we provided?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 9:08 ` Robert Millan
@ 2008-01-29 10:10 ` tgingold
2008-01-29 11:07 ` Robert Millan
0 siblings, 1 reply; 43+ messages in thread
From: tgingold @ 2008-01-29 10:10 UTC (permalink / raw)
To: The development of GRUB 2, Robert Millan; +Cc: The development of GRUB 2
Quoting Robert Millan <rmh@aybabtu.com>:
> On Tue, Jan 29, 2008 at 06:49:31AM +0100, Tristan Gingold wrote:
> > -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
>
> Don't these two break srcdir != objdir builds?
We wrote .mk files in srcdir, and this behaviour is kept. Did I miss your point
?
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 9:17 ` Robert Millan
@ 2008-01-29 10:31 ` tgingold
2008-01-29 11:08 ` Robert Millan
0 siblings, 1 reply; 43+ messages in thread
From: tgingold @ 2008-01-29 10:31 UTC (permalink / raw)
To: The development of GRUB 2, Robert Millan; +Cc: The development of GRUB 2
Quoting Robert Millan <rmh@aybabtu.com>:
> On Tue, Jan 29, 2008 at 06:12:52AM +0100, Tristan Gingold wrote:
> > > Have you checked if this trick works on other ports? Maybe it'd be a
> good idea
> > > to merge this first.
> >
> > I don't really understand what do you mean by 'works on other ports'. It
> is
> > designed to be an optionnal feature used only by ia64. Nothing IA64
> specific
> > and other ports may use it. If we go this way, it would be good to
> slightly
> > improve it.
>
> I suggest you just make sure it'll be usable on other ports in case a need
> arises, without going out of your way to support it.
Sure. I won't forget other ports. Anyway, there shouldn't be arch specific
code in this trick.
> > > > +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);
> > >
> > > Multiboot module loader in linux_normal.mod ?
> >
> > Well, well well. Long question :-)
> >
> > Ia64 doesn't really fit in multiboot: it's a full 64 bits processor,
>
> But there's multiboot2.
Right.
> > there
> > may be no room for an header in the 8KB (or you have to waste a lot of
> memory
> > to keep alignment), no room for EFI pointers in the header and no Ia64 OS
> > uses it. Well this were my conclusion when I read MB specs.
>
> Does this affect only EFI, or ia64 in general (e.g. ia64-coreboot, when that
> exists) ?
It's IA64 indeed.
> Also note the string "Load a Multiboot module." is present.
>
> If this is not multiboot, I'd suggest renaming the command to avoid name
> collisions (not only if multiboot is added later, but also user confusion).
Ok, I will rename the command and change the string, so this issue will be
closed.
> > > > diff -ruNp -x '*~' -x CVS 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-28 16:29:58.000000000 +0100
> > [...]
> > >
> > > This utility seems to be usable on i386 too? In that case, better to put
> it
> > > outside ia64/ dir?
> >
> > It should work on i386 too, but not tested.
> > I have written this utility for my port of EFI and adapted the style for
> > grub. It may be nice to share this code with i386 but not really required
> > now IMHO.
>
> util/i386/efi/grub-mkimage.c already generates PE, right? Why a different
> way to handle this? Sound like it'd be more consistent to either use elf2pe
> on both or share the same grub-mkimage. What do you think?
Having only one implementation is for sure a goal. But there are many
differences between the two implementations:
* grub-mkimage can only handle PE and I386.
* grub-mkimage can put modules image in a section.
* elf2pe can generate PE and PE+ and read I386 or IA64 ELF.
Enhancing grub-mkimage is not a small work as there are a lot of 32 bits types.
And in any case we have to test the two implementations (doable).
In my opinion, there is no need to hurry here. The both implementations work,
they do slightly different job, do not require maintainance and we can do
the merge later.
Tristan.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 9:59 ` Robert Millan
@ 2008-01-29 10:35 ` tgingold
2008-01-29 11:32 ` Robert Millan
2008-02-05 22:49 ` Alexandre Boeglin
1 sibling, 1 reply; 43+ messages in thread
From: tgingold @ 2008-01-29 10:35 UTC (permalink / raw)
To: The development of GRUB 2, Robert Millan; +Cc: The development of GRUB 2
Quoting Robert Millan <rmh@aybabtu.com>:
> > > Why is this needed? I'm not sure if it's good to exploit this
> "unreliability"
> > > feature that fat provides us ;-)
> >
> > On EFI, the prefix is extracted from an EFI path, whose case may not match
> > the FAT entries.
>
> Can you be more specific about this? What do the specs say? We wrote
> /boot/grub ourselves via grub-install; is an EFI-compliant firmware
> allowed to actively mess up case in paths we provided?
On EFI, we don't really know where grub is stored. There is a filesystem
layout convention we'd better to follow. As a consequence, we extract the
path from an EFI structure (I didn't write this code - it's in the EFI common
code).
Did I answer to all your concerns on this topic ?
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 10:10 ` tgingold
@ 2008-01-29 11:07 ` Robert Millan
2008-01-29 12:53 ` tgingold
0 siblings, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-01-29 11:07 UTC (permalink / raw)
To: tgingold; +Cc: The development of GRUB 2
On Tue, Jan 29, 2008 at 11:10:21AM +0100, tgingold@free.fr wrote:
> Quoting Robert Millan <rmh@aybabtu.com>:
>
> > On Tue, Jan 29, 2008 at 06:49:31AM +0100, Tristan Gingold wrote:
> > > -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
> >
> > Don't these two break srcdir != objdir builds?
>
> We wrote .mk files in srcdir, and this behaviour is kept. Did I miss your point
> ?
But mkfile generation itself can also happen when srcdir != objdir, can it?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 10:31 ` tgingold
@ 2008-01-29 11:08 ` Robert Millan
0 siblings, 0 replies; 43+ messages in thread
From: Robert Millan @ 2008-01-29 11:08 UTC (permalink / raw)
To: tgingold; +Cc: The development of GRUB 2
On Tue, Jan 29, 2008 at 11:31:21AM +0100, tgingold@free.fr wrote:
> > util/i386/efi/grub-mkimage.c already generates PE, right? Why a different
> > way to handle this? Sound like it'd be more consistent to either use elf2pe
> > on both or share the same grub-mkimage. What do you think?
>
> Having only one implementation is for sure a goal. But there are many
> differences between the two implementations:
>
> * grub-mkimage can only handle PE and I386.
> * grub-mkimage can put modules image in a section.
> * elf2pe can generate PE and PE+ and read I386 or IA64 ELF.
>
> Enhancing grub-mkimage is not a small work as there are a lot of 32 bits types.
> And in any case we have to test the two implementations (doable).
>
> In my opinion, there is no need to hurry here. The both implementations work,
> they do slightly different job, do not require maintainance and we can do
> the merge later.
No objection from me.
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 10:35 ` tgingold
@ 2008-01-29 11:32 ` Robert Millan
2008-01-29 12:56 ` tgingold
0 siblings, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-01-29 11:32 UTC (permalink / raw)
To: tgingold; +Cc: The development of GRUB 2
On Tue, Jan 29, 2008 at 11:35:26AM +0100, tgingold@free.fr wrote:
> Quoting Robert Millan <rmh@aybabtu.com>:
> > > > Why is this needed? I'm not sure if it's good to exploit this
> > "unreliability"
> > > > feature that fat provides us ;-)
> > >
> > > On EFI, the prefix is extracted from an EFI path, whose case may not match
> > > the FAT entries.
> >
> > Can you be more specific about this? What do the specs say? We wrote
> > /boot/grub ourselves via grub-install; is an EFI-compliant firmware
> > allowed to actively mess up case in paths we provided?
>
> On EFI, we don't really know where grub is stored. There is a filesystem
> layout convention we'd better to follow. As a consequence, we extract the
> path from an EFI structure (I didn't write this code - it's in the EFI common
> code).
What would you think of case-insensitive search in grub_efi_set_prefix() ?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 11:07 ` Robert Millan
@ 2008-01-29 12:53 ` tgingold
2008-01-29 13:39 ` Robert Millan
0 siblings, 1 reply; 43+ messages in thread
From: tgingold @ 2008-01-29 12:53 UTC (permalink / raw)
To: Robert Millan; +Cc: tgingold, The development of GRUB 2
Quoting Robert Millan <rmh@aybabtu.com>:
> On Tue, Jan 29, 2008 at 11:10:21AM +0100, tgingold@free.fr wrote:
> > Quoting Robert Millan <rmh@aybabtu.com>:
> >
> > > On Tue, Jan 29, 2008 at 06:49:31AM +0100, Tristan Gingold wrote:
> > > > -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
> > >
> > > Don't these two break srcdir != objdir builds?
> >
> > We wrote .mk files in srcdir, and this behaviour is kept. Did I miss your
> point
> > ?
>
> But mkfile generation itself can also happen when srcdir != objdir, can it?
Right. I fail to understand your point: how did the patch break srcdir !=
objdir ? I tested it with srcdir != objdir.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 11:32 ` Robert Millan
@ 2008-01-29 12:56 ` tgingold
2008-01-29 13:19 ` Robert Millan
0 siblings, 1 reply; 43+ messages in thread
From: tgingold @ 2008-01-29 12:56 UTC (permalink / raw)
To: Robert Millan; +Cc: tgingold, The development of GRUB 2
Quoting Robert Millan <rmh@aybabtu.com>:
> On Tue, Jan 29, 2008 at 11:35:26AM +0100, tgingold@free.fr wrote:
> > Quoting Robert Millan <rmh@aybabtu.com>:
> > > > > Why is this needed? I'm not sure if it's good to exploit this
> > > "unreliability"
> > > > > feature that fat provides us ;-)
> > > >
> > > > On EFI, the prefix is extracted from an EFI path, whose case may not
> match
> > > > the FAT entries.
> > >
> > > Can you be more specific about this? What do the specs say? We wrote
> > > /boot/grub ourselves via grub-install; is an EFI-compliant firmware
> > > allowed to actively mess up case in paths we provided?
> >
> > On EFI, we don't really know where grub is stored. There is a filesystem
> > layout convention we'd better to follow. As a consequence, we extract the
> > path from an EFI structure (I didn't write this code - it's in the EFI
> common
> > code).
>
> What would you think of case-insensitive search in grub_efi_set_prefix() ?
You mean walking the filesystem in grub_efi_set_prefix ? Humm, this looks
like a hack. The filesystem may not be FAT and there may be no way to read
directory entries (eg tftp - even if not yet supported).
If you really don't like it I can put it away for now. Grub should work
without this patch in most cases.
Tristan.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 12:56 ` tgingold
@ 2008-01-29 13:19 ` Robert Millan
2008-01-29 14:46 ` Marco Gerards
0 siblings, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-01-29 13:19 UTC (permalink / raw)
To: tgingold; +Cc: The development of GRUB 2
On Tue, Jan 29, 2008 at 01:56:49PM +0100, tgingold@free.fr wrote:
> Quoting Robert Millan <rmh@aybabtu.com>:
>
> > On Tue, Jan 29, 2008 at 11:35:26AM +0100, tgingold@free.fr wrote:
> > > Quoting Robert Millan <rmh@aybabtu.com>:
> > > > > > Why is this needed? I'm not sure if it's good to exploit this
> > > > "unreliability"
> > > > > > feature that fat provides us ;-)
> > > > >
> > > > > On EFI, the prefix is extracted from an EFI path, whose case may not
> > match
> > > > > the FAT entries.
> > > >
> > > > Can you be more specific about this? What do the specs say? We wrote
> > > > /boot/grub ourselves via grub-install; is an EFI-compliant firmware
> > > > allowed to actively mess up case in paths we provided?
> > >
> > > On EFI, we don't really know where grub is stored. There is a filesystem
> > > layout convention we'd better to follow. As a consequence, we extract the
> > > path from an EFI structure (I didn't write this code - it's in the EFI
> > common
> > > code).
> >
> > What would you think of case-insensitive search in grub_efi_set_prefix() ?
>
> You mean walking the filesystem in grub_efi_set_prefix ? Humm, this looks
> like a hack.
It does, I admit ;-). From my POV, it's a workaround for a bug, and it's not
so strange that workarounds tend to look like ugly hacks.
Anyway, does EFI replace the string with a case-unsensitive equivalent in
practise?
> The filesystem may not be FAT and there may be no way to read
> directory entries (eg tftp - even if not yet supported).
You can still do this kind of search by stating for a lot of specific files
instead of iterating. This would be a PITA, though :-(
> If you really don't like it I can put it away for now. Grub should work
> without this patch in most cases.
Could you wait untill the maintainers have their say on this? If Marco or
Okuji think it is fine, I have no objection then.
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 5:49 ` Tristan Gingold
2008-01-29 9:08 ` Robert Millan
@ 2008-01-29 13:36 ` Robert Millan
1 sibling, 0 replies; 43+ messages in thread
From: Robert Millan @ 2008-01-29 13:36 UTC (permalink / raw)
To: The development of GRUB 2
On Tue, Jan 29, 2008 at 06:49:31AM +0100, Tristan Gingold wrote:
> Hi,
>
> here is my new version of the patch. I think all the comments have been
> addressed.
> (There are still // comments in the .S files I copied from glibc. I suppose
> this is OK as the files come as-is from glibc).
Uhm looks like the patch is messed up somehow:
patch: **** malformed patch at line 1755: 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
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 12:53 ` tgingold
@ 2008-01-29 13:39 ` Robert Millan
0 siblings, 0 replies; 43+ messages in thread
From: Robert Millan @ 2008-01-29 13:39 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: tgingold
On Tue, Jan 29, 2008 at 01:53:03PM +0100, tgingold@free.fr wrote:
> >
> > But mkfile generation itself can also happen when srcdir != objdir, can it?
>
> Right. I fail to understand your point: how did the patch break srcdir !=
> objdir ? I tested it with srcdir != objdir.
Ah, sorry I read the patch wrong. I thought you were removing $(srcdir)
rather than moving it from one place to another.
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 13:19 ` Robert Millan
@ 2008-01-29 14:46 ` Marco Gerards
2008-01-29 15:30 ` Robert Millan
` (4 more replies)
0 siblings, 5 replies; 43+ messages in thread
From: Marco Gerards @ 2008-01-29 14:46 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: tgingold
Robert Millan <rmh@aybabtu.com> writes:
> On Tue, Jan 29, 2008 at 01:56:49PM +0100, tgingold@free.fr wrote:
>> Quoting Robert Millan <rmh@aybabtu.com>:
>>
>> > On Tue, Jan 29, 2008 at 11:35:26AM +0100, tgingold@free.fr wrote:
>> > > Quoting Robert Millan <rmh@aybabtu.com>:
>> > > > > > Why is this needed? I'm not sure if it's good to exploit this
>> > > > "unreliability"
>> > > > > > feature that fat provides us ;-)
>> > > > >
>> > > > > On EFI, the prefix is extracted from an EFI path, whose case may not
>> > match
>> > > > > the FAT entries.
>> > > >
>> > > > Can you be more specific about this? What do the specs say? We wrote
>> > > > /boot/grub ourselves via grub-install; is an EFI-compliant firmware
>> > > > allowed to actively mess up case in paths we provided?
>> > >
>> > > On EFI, we don't really know where grub is stored. There is a filesystem
>> > > layout convention we'd better to follow. As a consequence, we extract the
>> > > path from an EFI structure (I didn't write this code - it's in the EFI
>> > common
>> > > code).
>> >
>> > What would you think of case-insensitive search in grub_efi_set_prefix() ?
>>
>> You mean walking the filesystem in grub_efi_set_prefix ? Humm, this looks
>> like a hack.
>
> It does, I admit ;-). From my POV, it's a workaround for a bug, and it's not
> so strange that workarounds tend to look like ugly hacks.
>
> Anyway, does EFI replace the string with a case-unsensitive equivalent in
> practise?
>
>> The filesystem may not be FAT and there may be no way to read
>> directory entries (eg tftp - even if not yet supported).
>
> You can still do this kind of search by stating for a lot of specific files
> instead of iterating. This would be a PITA, though :-(
>
>> If you really don't like it I can put it away for now. Grub should work
>> without this patch in most cases.
>
> Could you wait untill the maintainers have their say on this? If Marco or
> Okuji think it is fine, I have no objection then.
Personally I do not like working around an issue in specific code (in
this case specific to *-efi) in generic code. Usually, this doesn't
improve shared code.
In this case, FAT is modified so fit the need of EFI. However, FAT is
case insensitive. On windows C:\FOO.TXT is the same as c:\foo.txt.
Although I have troubles believing people want to use a technically
flawed non-free OS that costs a lot of money. But that might be
something personally ;-)
What matters is that it is normal that FAT is not case sensitive.
It's defined that way. This change can't and won't be made for ext2,
for example. You can have a ~/foo and ~/FOO side by side. AFAIK,
this is not possible with FAT. So I think this patch is ok :-)
Robert suggested some changes. I also noticed in the discussion that
you didn't follow common practise (like an existing grub-mkimage
implementation). Personally, as maintainer, I am against maintaining
two different approaches of the same problem. It costs us time to
maintain this and both case have separate bugs. So I rather see the
code shared, one way or the other. To safe time, it might save you
some work if you initiate a discussion about this.
If you send in a new patch that addresses Robert's concerns +
Changelog entry, I will go over it ASAP :-). Giving the same comments
as Robert does seems like a waste of time for everyone. Is this ok
for you?
--
Marco
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 14:46 ` Marco Gerards
@ 2008-01-29 15:30 ` Robert Millan
2008-01-29 16:38 ` tgingold
2008-01-29 16:35 ` tgingold
` (3 subsequent siblings)
4 siblings, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-01-29 15:30 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: tgingold
On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> In this case, FAT is modified so fit the need of EFI. However, FAT is
> case insensitive. On windows C:\FOO.TXT is the same as c:\foo.txt.
> Although I have troubles believing people want to use a technically
> flawed non-free OS that costs a lot of money. But that might be
> something personally ;-)
>
> What matters is that it is normal that FAT is not case sensitive.
> It's defined that way. This change can't and won't be made for ext2,
> for example. You can have a ~/foo and ~/FOO side by side. AFAIK,
> this is not possible with FAT. So I think this patch is ok :-)
I may lack some perspective on how FAT works internally, so please bear with
me, but as far as I can see:
- FAT is not really case insensitive any more than its path names are
8.3-limited. It originally was, but latest revisions don't enforce
these limitations.
- For backwards compatibility with legacy applications we don't really
care about, the _OS_ that usually operates on FAT uses case insensitive
file access (but not case insensitive directory listing!).
- The only remnant that we have from all of this, is that two different
files can't have names that match a case-insensitive comparison, which
doesn't really affect our problem which is finding a match through case
insensitive search.
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 14:46 ` Marco Gerards
2008-01-29 15:30 ` Robert Millan
@ 2008-01-29 16:35 ` tgingold
2008-01-30 5:48 ` Tristan Gingold
` (2 subsequent siblings)
4 siblings, 0 replies; 43+ messages in thread
From: tgingold @ 2008-01-29 16:35 UTC (permalink / raw)
To: Marco Gerards; +Cc: tgingold, The development of GRUB 2
Quoting Marco Gerards <mgerards@xs4all.nl>:
> Personally I do not like working around an issue in specific code (in
> this case specific to *-efi) in generic code. Usually, this doesn't
> improve shared code.
>
> In this case, FAT is modified so fit the need of EFI. However, FAT is
> case insensitive. On windows C:\FOO.TXT is the same as c:\foo.txt.
> Although I have troubles believing people want to use a technically
> flawed non-free OS that costs a lot of money. But that might be
> something personally ;-)
>
> What matters is that it is normal that FAT is not case sensitive.
> It's defined that way. This change can't and won't be made for ext2,
> for example. You can have a ~/foo and ~/FOO side by side. AFAIK,
> this is not possible with FAT. So I think this patch is ok :-)
Ok, I will send it separately (as it is not really ia64 specific).
> Robert suggested some changes. I also noticed in the discussion that
> you didn't follow common practise (like an existing grub-mkimage
> implementation). Personally, as maintainer, I am against maintaining
> two different approaches of the same problem. It costs us time to
> maintain this and both case have separate bugs. So I rather see the
> code shared, one way or the other. To safe time, it might save you
> some work if you initiate a discussion about this.
Ok.
> If you send in a new patch that addresses Robert's concerns +
> Changelog entry, I will go over it ASAP :-). Giving the same comments
> as Robert does seems like a waste of time for everyone. Is this ok
> for you?
Ok.
Tristan.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 15:30 ` Robert Millan
@ 2008-01-29 16:38 ` tgingold
2008-01-29 18:48 ` Robert Millan
0 siblings, 1 reply; 43+ messages in thread
From: tgingold @ 2008-01-29 16:38 UTC (permalink / raw)
To: Robert Millan; +Cc: tgingold, The development of GRUB 2
Quoting Robert Millan <rmh@aybabtu.com>:
> On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> > In this case, FAT is modified so fit the need of EFI. However, FAT is
> > case insensitive. On windows C:\FOO.TXT is the same as c:\foo.txt.
> > Although I have troubles believing people want to use a technically
> > flawed non-free OS that costs a lot of money. But that might be
> > something personally ;-)
> >
> > What matters is that it is normal that FAT is not case sensitive.
> > It's defined that way. This change can't and won't be made for ext2,
> > for example. You can have a ~/foo and ~/FOO side by side. AFAIK,
> > this is not possible with FAT. So I think this patch is ok :-)
>
> I may lack some perspective on how FAT works internally, so please bear with
> me, but as far as I can see:
>
> - FAT is not really case insensitive any more than its path names are
> 8.3-limited. It originally was, but latest revisions don't enforce
> these limitations.
FAT is now case preserving but still case insensitive. Like MacOS filesystem.
> - For backwards compatibility with legacy applications we don't really
> care about, the _OS_ that usually operates on FAT uses case insensitive
> file access (but not case insensitive directory listing!).
>
> - The only remnant that we have from all of this, is that two different
> files can't have names that match a case-insensitive comparison, which
> doesn't really affect our problem which is finding a match through case
> insensitive search.
Right.
Tristan.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 16:38 ` tgingold
@ 2008-01-29 18:48 ` Robert Millan
2008-01-30 5:23 ` Tristan Gingold
0 siblings, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-01-29 18:48 UTC (permalink / raw)
To: tgingold; +Cc: The development of GRUB 2
On Tue, Jan 29, 2008 at 05:38:20PM +0100, tgingold@free.fr wrote:
> Quoting Robert Millan <rmh@aybabtu.com>:
>
> > On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> > > In this case, FAT is modified so fit the need of EFI. However, FAT is
> > > case insensitive. On windows C:\FOO.TXT is the same as c:\foo.txt.
> > > Although I have troubles believing people want to use a technically
> > > flawed non-free OS that costs a lot of money. But that might be
> > > something personally ;-)
> > >
> > > What matters is that it is normal that FAT is not case sensitive.
> > > It's defined that way. This change can't and won't be made for ext2,
> > > for example. You can have a ~/foo and ~/FOO side by side. AFAIK,
> > > this is not possible with FAT. So I think this patch is ok :-)
> >
> > I may lack some perspective on how FAT works internally, so please bear with
> > me, but as far as I can see:
> >
> > - FAT is not really case insensitive any more than its path names are
> > 8.3-limited. It originally was, but latest revisions don't enforce
> > these limitations.
>
> FAT is now case preserving but still case insensitive. Like MacOS filesystem.
AFAIK, there's no standard specifiing FAT, only a few implementations that act
de-facto as a "reference". Because of this, it is up to us to decide what is
"standard" and what is just an OS-dependant oddity.
Since the choice is arbitrary, why not choose based on the merits of each
option, rather than based on what some implementations do?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 18:48 ` Robert Millan
@ 2008-01-30 5:23 ` Tristan Gingold
2008-01-30 13:19 ` Robert Millan
0 siblings, 1 reply; 43+ messages in thread
From: Tristan Gingold @ 2008-01-30 5:23 UTC (permalink / raw)
To: Robert Millan; +Cc: tgingold, The development of GRUB 2
On Tue, Jan 29, 2008 at 07:48:29PM +0100, Robert Millan wrote:
[...]
> AFAIK, there's no standard specifiing FAT, only a few implementations that act
> de-facto as a "reference". Because of this, it is up to us to decide what is
> "standard" and what is just an OS-dependant oddity.
There are spefications from MS, eg:
Microsoft Extensible Firmware Initiative FAT32 File System Specification, rev. 1.03, December 6, 2000,
(http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx)
or even ECMA 107.
> Since the choice is arbitrary, why not choose based on the merits of each
> option, rather than based on what some implementations do?
Tristan.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 14:46 ` Marco Gerards
2008-01-29 15:30 ` Robert Millan
2008-01-29 16:35 ` tgingold
@ 2008-01-30 5:48 ` Tristan Gingold
2008-01-30 15:07 ` Robert Millan
` (3 more replies)
2008-01-30 5:48 ` Tristan Gingold
2008-01-30 5:57 ` Tristan Gingold
4 siblings, 4 replies; 43+ messages in thread
From: Tristan Gingold @ 2008-01-30 5:48 UTC (permalink / raw)
To: Marco Gerards; +Cc: tgingold, The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 428 bytes --]
On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> If you send in a new patch that addresses Robert's concerns +
> Changelog entry, I will go over it ASAP :-). Giving the same comments
> as Robert does seems like a waste of time for everyone. Is this ok
> for you?
Here is the IA64 port patch. I will send separately the FAT patch (optionnal)
and I will mail my proposal to merge the both efi tools.
Tristan.
[-- Attachment #2: grub.diffs3 --]
[-- Type: text/plain, Size: 129548 bytes --]
2008-01-28 Tristan Gingold <gingold@free.fr>
* 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.
* include/grub/efi/efi.h: Declare grub_efi_allocate_boot_pages and
grub_efi_free_boot_pages.
* 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/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 <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+
+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 <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#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/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}
#{@name}: #{pre_obj} #{mod_obj}
-rm -f $@
$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
- $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+ $(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 <http://www.gnu.org/licenses/>.
+ */
+
+#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-30 06:36:07.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 <http://www.gnu.org/licenses/>.
+ */
+
+#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_payload (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 <http://www.gnu.org/licenses/>.
+ */
+
+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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef GRUB_MACHINE_TIME_HEADER
+#define GRUB_MACHINE_TIME_HEADER 1
+
+#include <grub/efi/time.h>
+
+#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 <davidm@hpl.hp.com>.
+
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+#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/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 <grub/efi/api.h>
#include <grub/efi/efi.h>
+//#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 <http://www.gnu.org/licenses/>.
+ */
+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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/cache.h>
+#include <grub/kernel.h>
+#include <grub/efi/efi.h>
+
+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 <http://www.gnu.org/licenses/>.
+ */
+ .text
+ .psr abi64
+ .psr lsb
+ .lsb
+
+ .global _start
+ .proc _start
+_start:
+ alloc loc0=ar.pfs,2,4,0,0
+ mov loc1=rp
+ addl loc2=@gprel(grub_efi_image_handle),gp
+ addl loc3=@gprel(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 <http://www.gnu.org/licenses/>.
+ */
+ .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/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-30 06:39:57.000000000 +0100
@@ -0,0 +1,781 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/rescue.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/cache.h>
+#include <grub/kernel.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/elf.h>
+#include <grub/gzio.h>
+
+#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 payloads_chain;
+ grub_uint64_t payloads_nbr;
+};
+
+struct ia64_boot_payload
+{
+ grub_uint64_t start;
+ grub_uint64_t length;
+
+ /* Payload 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_payload *last_payload = 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,
+ (void *)&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,
+ (void *)&fpswa_protocol, (void *)&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_payload *payload;
+ struct ia64_boot_payload *next_payload;
+
+ /* Free payloads. */
+ payload = (struct ia64_boot_payload *)boot_param->payloads_chain;
+ while (payload != 0)
+ {
+ next_payload = (struct ia64_boot_payload *)payload->next;
+
+ grub_efi_free_boot_pages
+ (payload->start, page_align (payload->length) >> 12);
+ grub_efi_free_boot_pages ((grub_efi_physical_address_t)payload, 1);
+
+ payload = next_payload;
+ }
+
+ /* 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 = (grub_uint64_t)kernel_mem - low_addr;
+ grub_printf (" Relocated at %p (offset=%016lx)\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=%lx load=%lx memsz=%08lx "
+ "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) == (grub_off_t)-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 filename 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_payload (int argc, char *argv[])
+{
+ grub_file_t file = 0;
+ grub_ssize_t size, len = 0;
+ char *base = 0, *cmdline = 0, *p;
+ struct ia64_boot_payload *payload = 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 kernel first");
+ goto fail;
+ }
+
+ file = grub_gzfile_open (argv[0], 1);
+ if (! file)
+ goto fail;
+
+ size = grub_file_size (file);
+ base = grub_efi_allocate_boot_pages (0, page_align (size) >> 12);
+ if (! base)
+ goto fail;
+
+ grub_printf ("Payload %s [addr=%lx + %lx]\n",
+ argv[0], (grub_uint64_t)base, size);
+
+ if (grub_file_read (file, base, size) != size)
+ {
+ grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+ goto fail;
+ }
+
+ len = sizeof (struct ia64_boot_payload);
+ for (i = 0; i < argc; i++)
+ len += grub_strlen (argv[i]) + 1;
+
+ if (len > 4096)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "payload command line too long");
+ goto fail;
+ }
+ payload = grub_efi_allocate_boot_pages (0, 1);
+ if (! payload)
+ goto fail;
+
+ p = (char *)(payload + 1);
+
+ payload->start = (grub_uint64_t)base;
+ payload->length = size;
+ payload->cmdline = (grub_uint64_t)p;
+ payload->next = 0;
+
+ if (last_payload)
+ last_payload->next = (grub_uint64_t)payload;
+ else
+ {
+ last_payload = payload;
+ boot_param->payloads_chain = (grub_uint64_t)payload;
+ }
+ boot_param->payloads_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 (base);
+ 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 ("payload", grub_rescue_cmd_payload,
+ "load an additional file");
+ 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 ("payload");
+ 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-30 06:31:16.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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/loader.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+
+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_payload (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_rescue_cmd_payload (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
+ ("payload", grub_normal_cmd_payload,
+ GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+ "payload FILE [ARGS...]",
+ "Load an additional file.", 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 ("payload");
+ 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 <davidm@hpl.hp.com>.
+
+ 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 <davidm@hpl.hp.com>.
+
+ 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 <http://www.gnu.org/licenses/>.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <elf.h>
+
+#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 ELF2PE_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 ELF2PE_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 ELF2PE_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 ELF2PE_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 ELF2PE_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 ELF2PE_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 ELF2PE_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 ELF2PE_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 ELF2PE_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 ELF2PE_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 <http://www.gnu.org/licenses/>.
+
+
+# Initialize some variables.
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libdir=@libdir@
+datadir=@datadir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/${PACKAGE_TARNAME}/${target_cpu}-${platform}
+pkgdatadir=${datadir}/${PACKAGE_TARNAME}
+
+
+TARGET_CC=@TARGET_CC@
+TARGET_CFLAGS="@TARGET_CFLAGS@"
+TARGET_CPPFLAGS="@TARGET_CPPFLAGS@"
+TARGET_LDFLAGS="@TARGET_LDFLAGS@"
+OBJCOPY=@OBJCOPY@
+
+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
+Usage: grub-install [OPTION] install_device
+Install GRUB on your drive.
+
+ -h, --help print this message and exit
+ -v, --version print the version information and exit
+ --modules=MODULES pre-load specified modules MODULES
+ --root-directory=DIR install GRUB images under the directory DIR
+ instead of the root directory
+ --grub-setup=FILE use FILE as grub-setup
+ --grub-mkimage=FILE use FILE as grub-mkimage
+ --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
+ --grub-probefs=FILE use FILE as grub-probefs
+ --no-floppy do not probe any floppy drive
+ --recheck probe a device map even if it already exists
+
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+
+grub-install copies GRUB images into the DIR/boot directory specfied by
+--root-directory, and uses grub-setup to install grub into the boot
+sector.
+
+Report bugs to <bug-grub@gnu.org>.
+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 <http://www.gnu.org/licenses/>.
+ */
+#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
+
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 14:46 ` Marco Gerards
` (2 preceding siblings ...)
2008-01-30 5:48 ` Tristan Gingold
@ 2008-01-30 5:48 ` Tristan Gingold
2008-01-30 5:57 ` Tristan Gingold
4 siblings, 0 replies; 43+ messages in thread
From: Tristan Gingold @ 2008-01-30 5:48 UTC (permalink / raw)
To: Marco Gerards; +Cc: tgingold, The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 283 bytes --]
> If you send in a new patch that addresses Robert's concerns +
> Changelog entry, I will go over it ASAP :-). Giving the same comments
> as Robert does seems like a waste of time for everyone. Is this ok
> for you?
Here is the patch that makes FAT fs case insensitive.
Tristan.
[-- Attachment #2: grub-fat.diffs --]
[-- Type: text/plain, Size: 2573 bytes --]
2008-01-28 Tristan Gingold <gingold@free.fr>
* kern/misc.c (grub_strcasecmp): New function.
* include/grub/misc.h: Declare grub_strcasecmp.
* fs/fat.c (grub_fat_find_dir): Use case insensitive string
compare as filenames are not case sensitive.
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)
{
if (n == 0)
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/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);
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 14:46 ` Marco Gerards
` (3 preceding siblings ...)
2008-01-30 5:48 ` Tristan Gingold
@ 2008-01-30 5:57 ` Tristan Gingold
2008-01-30 13:25 ` Robert Millan
4 siblings, 1 reply; 43+ messages in thread
From: Tristan Gingold @ 2008-01-30 5:57 UTC (permalink / raw)
To: Marco Gerards; +Cc: tgingold, The development of GRUB 2
On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> Robert suggested some changes. I also noticed in the discussion that
> you didn't follow common practise (like an existing grub-mkimage
> implementation). Personally, as maintainer, I am against maintaining
> two different approaches of the same problem. It costs us time to
> maintain this and both case have separate bugs. So I rather see the
> code shared, one way or the other. To safe time, it might save you
> some work if you initiate a discussion about this.
The facts:
util/i386/efi/grub-mkimage.c and elf2pe.c do almost the same thing: converting
an ELF file to a PE file. But:
* the input format is slightly different (Elf32 vs Elf64)
* the output format is slightly different (PE vs PE+)
* the relocating work is different (x86 vs ia64, Rel vs Rela)
* The entry point is a descriptor on ia64
* grub-mkimage.c can insert modules in a section.
I propose to extend grub-mkimage.c so that it can handle ia64. I propose to
select at compile time which convertion to do through macro (see beginning
of elf2pe file to see an example). I don't think it is worth making a
generic grub-mkimage binary that can do any convertion: it's too much
code duplication.
Ok for this approach ?
Tristan.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 5:23 ` Tristan Gingold
@ 2008-01-30 13:19 ` Robert Millan
0 siblings, 0 replies; 43+ messages in thread
From: Robert Millan @ 2008-01-30 13:19 UTC (permalink / raw)
To: Tristan Gingold; +Cc: The development of GRUB 2
On Wed, Jan 30, 2008 at 06:23:09AM +0100, Tristan Gingold wrote:
> On Tue, Jan 29, 2008 at 07:48:29PM +0100, Robert Millan wrote:
> [...]
> > AFAIK, there's no standard specifiing FAT, only a few implementations that act
> > de-facto as a "reference". Because of this, it is up to us to decide what is
> > "standard" and what is just an OS-dependant oddity.
>
> There are spefications from MS, eg:
> Microsoft Extensible Firmware Initiative FAT32 File System Specification, rev. 1.03, December 6, 2000,
> (http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx)
Ok, I have downloaded the document without accepting their license (which is
completely legal where I live), and had a look it (or at least the part of it
that can be deciphered from MS-Office internal format).
I can't legally quote it, but it seems the requirement of case insensitivity
is present. I really think it is completely broken to describe a filesystem
structure saying, not how the data is organized, but how your implementation
must present it to the upper layer.
It is simply out of scope. Consider there was a document describing ext2 that
said /dev/zero, if present, must output an endless stream of 0xff.
> or even ECMA 107.
Also, note that neither of these qualify as "standards". The first is a
Microsoft internal document, the second is just a rubber-stamp organization.
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 5:57 ` Tristan Gingold
@ 2008-01-30 13:25 ` Robert Millan
2008-01-30 16:04 ` tgingold
0 siblings, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-01-30 13:25 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: tgingold
On Wed, Jan 30, 2008 at 06:57:34AM +0100, Tristan Gingold wrote:
> On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> > Robert suggested some changes. I also noticed in the discussion that
> > you didn't follow common practise (like an existing grub-mkimage
> > implementation). Personally, as maintainer, I am against maintaining
> > two different approaches of the same problem. It costs us time to
> > maintain this and both case have separate bugs. So I rather see the
> > code shared, one way or the other. To safe time, it might save you
> > some work if you initiate a discussion about this.
>
> The facts:
>
> util/i386/efi/grub-mkimage.c and elf2pe.c do almost the same thing: converting
> an ELF file to a PE file. But:
>
> * the input format is slightly different (Elf32 vs Elf64)
> * the output format is slightly different (PE vs PE+)
> * the relocating work is different (x86 vs ia64, Rel vs Rela)
> * The entry point is a descriptor on ia64
> * grub-mkimage.c can insert modules in a section.
Sounds like they're very different. Maybe it'd be fine to just change
the name and user interface from elf2pe.c to util/ia64/efi/grub-mkimage.c ?
What do you think?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 5:48 ` Tristan Gingold
@ 2008-01-30 15:07 ` Robert Millan
2008-01-30 15:33 ` Robert Millan
2008-01-30 16:22 ` tgingold
2008-02-04 15:45 ` Marco Gerards
` (2 subsequent siblings)
3 siblings, 2 replies; 43+ messages in thread
From: Robert Millan @ 2008-01-30 15:07 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: tgingold
On Wed, Jan 30, 2008 at 06:48:11AM +0100, Tristan Gingold wrote:
> +
> +# 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-probe is missing. Did you check if it works? Although, I think it
should just move to common.rmk. I'll have a look at that.
> 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
> [...]
> +grub_probefs=${sbindir}/grub-probefs
grub-probefs was renamed to grub-probe.
> +# 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
Why is this commented out? Is ${grubdir} a mount point to efi's boot
memory device? We do that on i386 (I don't claim that it is a good way,
in fact I dislike it and Okuji does as well, but if we want to change it I
expect we'll want to change it in both).
Also, missing partmap_module and devabstraction_module. I think you should
resync this with the latest version of i386/efi/grub-install.in.
> +modules="kernel
kernel isn't implicit?
> gpt
Is gpt mandatory? We can use gpt without efi; I wonder if we can also use
efi without gpt. If you can access the raw disk, any partition map (even no
partition map at all!) could be used, right?
> fat
Even if fat is mandated by the standard, I think it's safer to probe for that,
since we have the mechanism to do it (grub-probe also performs some sanity
checks that would detect if the fat is corrupted or so).
> gzio normal ls cat fshelp help _linux linux memmap systab boot
Why this selection specificaly? Other ports without significant size limit
just encourage the user to do "grub-mkimage *.mod -o foo" or manually select
what is needed.
Or it wasn't possible to load additional modules in runtime yet? I don't
remember well..
> +# 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
Is there a way we can do this before to avoid runtime dependency on binutils?
Btw has this been tested on i386-efi ?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 15:07 ` Robert Millan
@ 2008-01-30 15:33 ` Robert Millan
2008-01-30 16:22 ` tgingold
1 sibling, 0 replies; 43+ messages in thread
From: Robert Millan @ 2008-01-30 15:33 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: tgingold
On Wed, Jan 30, 2008 at 04:07:01PM +0100, Robert Millan wrote:
>
> grub-probe is missing. Did you check if it works? Although, I think it
> should just move to common.rmk. I'll have a look at that.
It's in common.rmk now. Please, can you check that update-grub works for
ia64-efi ?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 13:25 ` Robert Millan
@ 2008-01-30 16:04 ` tgingold
2008-03-19 17:11 ` Robert Millan
0 siblings, 1 reply; 43+ messages in thread
From: tgingold @ 2008-01-30 16:04 UTC (permalink / raw)
To: Robert Millan; +Cc: tgingold, The development of GRUB 2
Quoting Robert Millan <rmh@aybabtu.com>:
> On Wed, Jan 30, 2008 at 06:57:34AM +0100, Tristan Gingold wrote:
> > On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> > > Robert suggested some changes. I also noticed in the discussion that
> > > you didn't follow common practise (like an existing grub-mkimage
> > > implementation). Personally, as maintainer, I am against maintaining
> > > two different approaches of the same problem. It costs us time to
> > > maintain this and both case have separate bugs. So I rather see the
> > > code shared, one way or the other. To safe time, it might save you
> > > some work if you initiate a discussion about this.
> >
> > The facts:
> >
> > util/i386/efi/grub-mkimage.c and elf2pe.c do almost the same thing:
> converting
> > an ELF file to a PE file. But:
> >
> > * the input format is slightly different (Elf32 vs Elf64)
> > * the output format is slightly different (PE vs PE+)
> > * the relocating work is different (x86 vs ia64, Rel vs Rela)
> > * The entry point is a descriptor on ia64
> > * grub-mkimage.c can insert modules in a section.
>
> Sounds like they're very different. Maybe it'd be fine to just change
> the name and user interface from elf2pe.c to util/ia64/efi/grub-mkimage.c ?
>
> What do you think?
Fine for me.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 15:07 ` Robert Millan
2008-01-30 15:33 ` Robert Millan
@ 2008-01-30 16:22 ` tgingold
2008-01-30 18:38 ` Robert Millan
1 sibling, 1 reply; 43+ messages in thread
From: tgingold @ 2008-01-30 16:22 UTC (permalink / raw)
To: Robert Millan; +Cc: tgingold, The development of GRUB 2
Quoting Robert Millan <rmh@aybabtu.com>:
> On Wed, Jan 30, 2008 at 06:48:11AM +0100, Tristan Gingold wrote:
>
> grub-probe is missing. Did you check if it works? Although, I think it
> should just move to common.rmk. I'll have a look at that.
Ok.
> > 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
> > [...]
> > +grub_probefs=${sbindir}/grub-probefs
>
> grub-probefs was renamed to grub-probe.
Ok, I missed that.
> > +# 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
>
> Why is this commented out? Is ${grubdir} a mount point to efi's boot
> memory device?
Yes.
> We do that on i386 (I don't claim that it is a good way,
> in fact I dislike it and Okuji does as well, but if we want to change it I
> expect we'll want to change it in both).
>
> Also, missing partmap_module and devabstraction_module. I think you should
> resync this with the latest version of i386/efi/grub-install.in.
Will do.
> > +modules="kernel
>
> kernel isn't implicit?
Should be.
> > gpt
>
> Is gpt mandatory?
Almost.
> We can use gpt without efi; I wonder if we can also use
> efi without gpt. If you can access the raw disk, any partition map (even no
> partition map at all!) could be used, right?
Not really. EFI has to load grub, and EFI only always knows GPT+FAT.
> > fat
>
> Even if fat is mandated by the standard, I think it's safer to probe for
> that,
> since we have the mechanism to do it (grub-probe also performs some sanity
> checks that would detect if the fat is corrupted or so).
Sure.
> > gzio normal ls cat fshelp help _linux linux memmap systab boot
>
> Why this selection specificaly?
That's the one I used and tested :-)
> Other ports without significant size limit
> just encourage the user to do "grub-mkimage *.mod -o foo" or manually select
> what is needed.
Ok.
> Or it wasn't possible to load additional modules in runtime yet? I don't
> remember well..
Yes, you currently can't dynload modules.
> > +# 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
>
> Is there a way we can do this before to avoid runtime dependency on binutils?
This is part of the module trick ;-). If we build a grub with all modules,
this is not necessary anymore.
> Btw has this been tested on i386-efi ?
No. I only have access to an EFI simulator on i386.
Tristan.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 16:22 ` tgingold
@ 2008-01-30 18:38 ` Robert Millan
0 siblings, 0 replies; 43+ messages in thread
From: Robert Millan @ 2008-01-30 18:38 UTC (permalink / raw)
To: tgingold; +Cc: The development of GRUB 2
On Wed, Jan 30, 2008 at 05:22:00PM +0100, tgingold@free.fr wrote:
> > Is gpt mandatory?
>
> Almost.
>
> > We can use gpt without efi; I wonder if we can also use
> > efi without gpt. If you can access the raw disk, any partition map (even no
> > partition map at all!) could be used, right?
>
> Not really. EFI has to load grub, and EFI only always knows GPT+FAT.
I see. Anyway, I still think it'd be a good idea to probe for it. Say,
if someone makes an extended version of EFI that supports other partition
maps, or so. And since we have the instruments to do it, why not?
> > Btw has this been tested on i386-efi ?
>
> No. I only have access to an EFI simulator on i386.
It doesn't cause regression on the simulator then? :-)
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 5:48 ` Tristan Gingold
2008-01-30 15:07 ` Robert Millan
@ 2008-02-04 15:45 ` Marco Gerards
2008-02-04 16:07 ` Robert Millan
2008-02-10 22:43 ` Alexandre Boeglin
2010-01-18 18:03 ` Robert Millan
3 siblings, 1 reply; 43+ messages in thread
From: Marco Gerards @ 2008-02-04 15:45 UTC (permalink / raw)
To: Tristan Gingold; +Cc: The development of GRUB 2
Tristan Gingold <tgingold@free.fr> writes:
> On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
>> If you send in a new patch that addresses Robert's concerns +
>> Changelog entry, I will go over it ASAP :-). Giving the same comments
>> as Robert does seems like a waste of time for everyone. Is this ok
>> for you?
>
> Here is the IA64 port patch. I will send separately the FAT patch (optionnal)
> and I will mail my proposal to merge the both efi tools.
Is this patch still relevant, or if I reply to this, will I comment on
old code?
--
Marco
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-02-04 15:45 ` Marco Gerards
@ 2008-02-04 16:07 ` Robert Millan
2008-02-05 9:51 ` tgingold
0 siblings, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-02-04 16:07 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: Tristan Gingold
On Mon, Feb 04, 2008 at 04:45:30PM +0100, Marco Gerards wrote:
> Tristan Gingold <tgingold@free.fr> writes:
>
> > On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> >> If you send in a new patch that addresses Robert's concerns +
> >> Changelog entry, I will go over it ASAP :-). Giving the same comments
> >> as Robert does seems like a waste of time for everyone. Is this ok
> >> for you?
> >
> > Here is the IA64 port patch. I will send separately the FAT patch (optionnal)
> > and I will mail my proposal to merge the both efi tools.
>
> Is this patch still relevant, or if I reply to this, will I comment on
> old code?
I think it is.
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-02-04 16:07 ` Robert Millan
@ 2008-02-05 9:51 ` tgingold
0 siblings, 0 replies; 43+ messages in thread
From: tgingold @ 2008-02-05 9:51 UTC (permalink / raw)
To: The development of GRUB 2, Robert Millan; +Cc: Tristan Gingold
Quoting Robert Millan <rmh@aybabtu.com>:
> On Mon, Feb 04, 2008 at 04:45:30PM +0100, Marco Gerards wrote:
> > Tristan Gingold <tgingold@free.fr> writes:
> >
> > > On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> > >> If you send in a new patch that addresses Robert's concerns +
> > >> Changelog entry, I will go over it ASAP :-). Giving the same comments
> > >> as Robert does seems like a waste of time for everyone. Is this ok
> > >> for you?
> > >
> > > Here is the IA64 port patch. I will send separately the FAT patch
> (optionnal)
> > > and I will mail my proposal to merge the both efi tools.
> >
> > Is this patch still relevant, or if I reply to this, will I comment on
> > old code?
>
> I think it is.
Still relevant and independent on the remaining ia64 patches.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-29 9:59 ` Robert Millan
2008-01-29 10:35 ` tgingold
@ 2008-02-05 22:49 ` Alexandre Boeglin
1 sibling, 0 replies; 43+ messages in thread
From: Alexandre Boeglin @ 2008-02-05 22:49 UTC (permalink / raw)
To: The development of GRUB 2
Le mar 29 jan 2008 à 10:59:22 +0100, Robert Millan a écrit :
> > On EFI, the prefix is extracted from an EFI path, whose case may not match
> > the FAT entries.
>
> Can you be more specific about this? What do the specs say? We wrote
> /boot/grub ourselves via grub-install; is an EFI-compliant firmware
> allowed to actively mess up case in paths we provided?
Actually, kern/efi/init.c:grub_efi_set_prefix does not use the "user defined"
grub_prefix at all.
Currently, it gets the device path of the grub.efi binary, and traverses to
there. So, it only works when the modules are in the same directory as
grub.efi itself.
On the other hand, as the path is extracted using EFI's API (IIRC), it sounds
like an EFI bug that it mises up case like this. So the FAT case sensitivity
patch is then inevitable ...
Alex
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 5:48 ` Tristan Gingold
2008-01-30 15:07 ` Robert Millan
2008-02-04 15:45 ` Marco Gerards
@ 2008-02-10 22:43 ` Alexandre Boeglin
2008-02-11 8:59 ` tgingold
2010-01-18 18:03 ` Robert Millan
3 siblings, 1 reply; 43+ messages in thread
From: Alexandre Boeglin @ 2008-02-10 22:43 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: tgingold
Le mer 30 jan 2008 à 06:48:11 +0100, Tristan Gingold a écrit :
> * loader/ia64/efi/linux_normal.c: New file.
> * loader/ia64/efi/linux.c: New file.
Hello,
Wouldn't it be possible to merge these and the current loader/i386/efi/linux*
into one single loader/efi/linux.c and linux_normal.c ?
As far as I've seen, the only IA64 specific part is the FPSWA driver.
Alex
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-02-10 22:43 ` Alexandre Boeglin
@ 2008-02-11 8:59 ` tgingold
0 siblings, 0 replies; 43+ messages in thread
From: tgingold @ 2008-02-11 8:59 UTC (permalink / raw)
To: Alexandre Boeglin; +Cc: tgingold, The development of GRUB 2
Quoting Alexandre Boeglin <alex@boeglin.org>:
> Le mer 30 jan 2008 à 06:48:11 +0100, Tristan Gingold a écrit :
> > * loader/ia64/efi/linux_normal.c: New file.
> > * loader/ia64/efi/linux.c: New file.
>
> Hello,
>
> Wouldn't it be possible to merge these and the current loader/i386/efi/linux*
> into one single loader/efi/linux.c and linux_normal.c ?
>
> As far as I've seen, the only IA64 specific part is the FPSWA driver.
Not only.
The parameters are very different, the jump to the kernel too as well as
the memory allocation (we don't want to bother with < 1 MB limit on ia64).
Very few common lines as a consequence.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 16:04 ` tgingold
@ 2008-03-19 17:11 ` Robert Millan
2008-03-20 6:34 ` Tristan Gingold
0 siblings, 1 reply; 43+ messages in thread
From: Robert Millan @ 2008-03-19 17:11 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: tgingold
On Wed, Jan 30, 2008 at 05:04:18PM +0100, tgingold@free.fr wrote:
> Quoting Robert Millan <rmh@aybabtu.com>:
>
> > On Wed, Jan 30, 2008 at 06:57:34AM +0100, Tristan Gingold wrote:
> > > On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> > > > Robert suggested some changes. I also noticed in the discussion that
> > > > you didn't follow common practise (like an existing grub-mkimage
> > > > implementation). Personally, as maintainer, I am against maintaining
> > > > two different approaches of the same problem. It costs us time to
> > > > maintain this and both case have separate bugs. So I rather see the
> > > > code shared, one way or the other. To safe time, it might save you
> > > > some work if you initiate a discussion about this.
> > >
> > > The facts:
> > >
> > > util/i386/efi/grub-mkimage.c and elf2pe.c do almost the same thing:
> > converting
> > > an ELF file to a PE file. But:
> > >
> > > * the input format is slightly different (Elf32 vs Elf64)
> > > * the output format is slightly different (PE vs PE+)
> > > * the relocating work is different (x86 vs ia64, Rel vs Rela)
> > > * The entry point is a descriptor on ia64
> > > * grub-mkimage.c can insert modules in a section.
> >
> > Sounds like they're very different. Maybe it'd be fine to just change
> > the name and user interface from elf2pe.c to util/ia64/efi/grub-mkimage.c ?
> >
> > What do you think?
>
> Fine for me.
Will you send a new patch for this?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-03-19 17:11 ` Robert Millan
@ 2008-03-20 6:34 ` Tristan Gingold
0 siblings, 0 replies; 43+ messages in thread
From: Tristan Gingold @ 2008-03-20 6:34 UTC (permalink / raw)
To: Robert Millan; +Cc: tgingold, The development of GRUB 2
On Wed, Mar 19, 2008 at 06:11:31PM +0100, Robert Millan wrote:
[...]
> > Fine for me.
>
> Will you send a new patch for this?
Yes, I still plan to update my patches. But I am currently out of time...
Tristan.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: IA64 port
2008-01-30 5:48 ` Tristan Gingold
` (2 preceding siblings ...)
2008-02-10 22:43 ` Alexandre Boeglin
@ 2010-01-18 18:03 ` Robert Millan
3 siblings, 0 replies; 43+ messages in thread
From: Robert Millan @ 2010-01-18 18:03 UTC (permalink / raw)
To: The development of GRUB 2; +Cc: tgingold
On Wed, Jan 30, 2008 at 06:48:11AM +0100, Tristan Gingold wrote:
> On Tue, Jan 29, 2008 at 03:46:50PM +0100, Marco Gerards wrote:
> > If you send in a new patch that addresses Robert's concerns +
> > Changelog entry, I will go over it ASAP :-). Giving the same comments
> > as Robert does seems like a waste of time for everyone. Is this ok
> > for you?
>
> Here is the IA64 port patch. I will send separately the FAT patch (optionnal)
> and I will mail my proposal to merge the both efi tools.
Hi!
I put your patch in /branches/ia64/ in our Bazaar repository and resynced it
with latest trunk, then fixed a ton of trivial build problems.
Unfortunately I can't test it. If you can test it and confirm it works, we
could consider it for merging into experimental branch. Although we'd need
to figure out what we do about missing loadable module support.
(btw FAT fixes were merged separately)
--
Robert Millan
"Be the change you want to see in the world" -- Gandhi
^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2010-01-18 18:03 UTC | newest]
Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-28 16:09 IA64 port Tristan Gingold
2008-01-28 16:55 ` Robert Millan
2008-01-29 5:12 ` Tristan Gingold
2008-01-29 9:17 ` Robert Millan
2008-01-29 10:31 ` tgingold
2008-01-29 11:08 ` Robert Millan
2008-01-29 9:59 ` Robert Millan
2008-01-29 10:35 ` tgingold
2008-01-29 11:32 ` Robert Millan
2008-01-29 12:56 ` tgingold
2008-01-29 13:19 ` Robert Millan
2008-01-29 14:46 ` Marco Gerards
2008-01-29 15:30 ` Robert Millan
2008-01-29 16:38 ` tgingold
2008-01-29 18:48 ` Robert Millan
2008-01-30 5:23 ` Tristan Gingold
2008-01-30 13:19 ` Robert Millan
2008-01-29 16:35 ` tgingold
2008-01-30 5:48 ` Tristan Gingold
2008-01-30 15:07 ` Robert Millan
2008-01-30 15:33 ` Robert Millan
2008-01-30 16:22 ` tgingold
2008-01-30 18:38 ` Robert Millan
2008-02-04 15:45 ` Marco Gerards
2008-02-04 16:07 ` Robert Millan
2008-02-05 9:51 ` tgingold
2008-02-10 22:43 ` Alexandre Boeglin
2008-02-11 8:59 ` tgingold
2010-01-18 18:03 ` Robert Millan
2008-01-30 5:48 ` Tristan Gingold
2008-01-30 5:57 ` Tristan Gingold
2008-01-30 13:25 ` Robert Millan
2008-01-30 16:04 ` tgingold
2008-03-19 17:11 ` Robert Millan
2008-03-20 6:34 ` Tristan Gingold
2008-02-05 22:49 ` Alexandre Boeglin
2008-01-29 5:49 ` Tristan Gingold
2008-01-29 9:08 ` Robert Millan
2008-01-29 10:10 ` tgingold
2008-01-29 11:07 ` Robert Millan
2008-01-29 12:53 ` tgingold
2008-01-29 13:39 ` Robert Millan
2008-01-29 13:36 ` Robert Millan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.