From 2c40cc7868265137b8b8e0bbfc16f004d792c8cf Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 14:17:47 +0000 Subject: [PATCH 001/211] Import Tristan Gingold's ia64 port (based on patch sent to grub-devel by Tristan in 2008-01-28) --- ChangeLog.ia64 | 45 ++ Makefile.in | 3 +- commands/efi/acpi.c | 193 ++++++++ commands/efi/memmap.c | 143 ++++++ commands/efi/systab.c | 258 +++++++++++ conf/ia64-efi.rmk | 122 +++++ configure.ac | 5 +- geninit.sh | 2 +- genmk.rb | 2 +- include/grub/dl.h | 14 +- include/grub/efi/efi.h | 7 + include/grub/ia64/efi/kernel.h | 33 ++ include/grub/ia64/efi/loader.h | 30 ++ include/grub/ia64/efi/misc.h | 24 + include/grub/ia64/efi/time.h | 23 + include/grub/ia64/setjmp.h | 31 ++ include/grub/ia64/time.h | 28 ++ include/grub/ia64/types.h | 32 ++ include/grub/kernel.h | 2 +- kern/dl.c | 23 + kern/efi/mm.c | 90 ++-- kern/ia64/efi/elf_ia64_efi.lds | 84 ++++ kern/ia64/efi/init.c | 59 +++ kern/ia64/efi/startup.S | 40 ++ kern/ia64/trampoline.S | 38 ++ loader/ia64/efi/linux.c | 776 +++++++++++++++++++++++++++++++ loader/ia64/efi/linux_normal.c | 107 +++++ normal/ia64/longjmp.S | 162 +++++++ normal/ia64/setjmp.S | 171 +++++++ util/ia64/efi/elf2pe.c | 812 +++++++++++++++++++++++++++++++++ util/ia64/efi/grub-install.in | 233 ++++++++++ util/ia64/efi/pe32.h | 237 ++++++++++ 32 files changed, 3791 insertions(+), 38 deletions(-) create mode 100644 ChangeLog.ia64 create mode 100644 commands/efi/acpi.c create mode 100644 commands/efi/memmap.c create mode 100644 commands/efi/systab.c create mode 100644 conf/ia64-efi.rmk create mode 100644 include/grub/ia64/efi/kernel.h create mode 100644 include/grub/ia64/efi/loader.h create mode 100644 include/grub/ia64/efi/misc.h create mode 100644 include/grub/ia64/efi/time.h create mode 100644 include/grub/ia64/setjmp.h create mode 100644 include/grub/ia64/time.h create mode 100644 include/grub/ia64/types.h create mode 100644 kern/ia64/efi/elf_ia64_efi.lds create mode 100644 kern/ia64/efi/init.c create mode 100644 kern/ia64/efi/startup.S create mode 100644 kern/ia64/trampoline.S create mode 100644 loader/ia64/efi/linux.c create mode 100644 loader/ia64/efi/linux_normal.c create mode 100644 normal/ia64/longjmp.S create mode 100644 normal/ia64/setjmp.S create mode 100644 util/ia64/efi/elf2pe.c create mode 100644 util/ia64/efi/grub-install.in create mode 100644 util/ia64/efi/pe32.h diff --git a/ChangeLog.ia64 b/ChangeLog.ia64 new file mode 100644 index 000000000..35417bec0 --- /dev/null +++ b/ChangeLog.ia64 @@ -0,0 +1,45 @@ +2008-01-28 Tristan Gingold + + * geninit.sh: Call _init with a null argument. + * configure.ac: Add ia64-efi target. + * Makefile.in (STRIP_FLAGS): Declare (overriden on ia64). + (RMKFILES): 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. + * 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 --git a/Makefile.in b/Makefile.in index 84b4e9c7c..134505d3c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 --git a/commands/efi/acpi.c b/commands/efi/acpi.c new file mode 100644 index 000000000..ea9783f00 --- /dev/null +++ b/commands/efi/acpi.c @@ -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 . + */ +#include +#include +#include +#include + +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 --git a/commands/efi/memmap.c b/commands/efi/memmap.c new file mode 100644 index 000000000..a3ce82841 --- /dev/null +++ b/commands/efi/memmap.c @@ -0,0 +1,143 @@ +/* memmap.c - Display memory map. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ +#include +#include +#include +#include +#include +#include + +#define ADD_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +static grub_err_t +grub_cmd_memmap (struct grub_arg_list *state, int argc, char **args) +{ + grub_efi_uintn_t map_size; + grub_efi_memory_descriptor_t *memory_map; + grub_efi_memory_descriptor_t *memory_map_end; + grub_efi_memory_descriptor_t *desc; + grub_efi_uintn_t desc_size; + + map_size = 0; + if (grub_efi_get_memory_map (&map_size, NULL, NULL, &desc_size, 0) < 0) + return 0; + + memory_map = grub_malloc (map_size); + if (memory_map == NULL) + return 0; + if (grub_efi_get_memory_map (&map_size, memory_map, NULL, &desc_size, 0) < 0) + goto fail; + + grub_set_more (1); + + grub_printf + ("Type Physical start - end #Pages " + " Size Attributes\n"); + memory_map_end = ADD_MEMORY_DESCRIPTOR(memory_map, map_size); + for (desc = memory_map; + desc < memory_map_end; + desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) + { + grub_efi_uintn_t size; + grub_efi_uint64_t attr; + static const char types_str[][9] = + { + "reserved", + "ldr-code", + "ldr-data", + "BS-code ", + "BS-data ", + "RT-code ", + "RT-data ", + "conv-mem", + "unusable", + "ACPI-rec", + "ACPI-nvs", + "MMIO ", + "IO-ports", + "PAL-code" + }; + if (desc->type < sizeof (types_str) / sizeof (types_str[0])) + grub_printf ("%s ", types_str[desc->type]); + else + grub_printf ("Unk %02x ", desc->type); + + grub_printf (" %016llx-%016llx %08lx", + desc->physical_start, + desc->physical_start + (desc->num_pages << 12) - 1, + desc->num_pages); + + size = desc->num_pages << (12 - 10); + if (size < 1024) + grub_printf (" %4uKB", size); + else + { + size /= 1024; + if (size < 1024) + grub_printf (" %4uMB", size); + else + { + size /= 1024; + grub_printf (" %4uGB", size); + } + } + + attr = desc->attribute; + if (attr & GRUB_EFI_MEMORY_RUNTIME) + grub_printf (" RT"); + if (attr & GRUB_EFI_MEMORY_UC) + grub_printf (" UC"); + if (attr & GRUB_EFI_MEMORY_WC) + grub_printf (" WC"); + if (attr & GRUB_EFI_MEMORY_WT) + grub_printf (" WT"); + if (attr & GRUB_EFI_MEMORY_WB) + grub_printf (" WB"); + if (attr & GRUB_EFI_MEMORY_UCE) + grub_printf (" UCE"); + if (attr & GRUB_EFI_MEMORY_WP) + grub_printf (" WP"); + if (attr & GRUB_EFI_MEMORY_RP) + grub_printf (" RP"); + if (attr & GRUB_EFI_MEMORY_XP) + grub_printf (" XP"); + + grub_printf ("\n"); + } + + grub_set_more (0); + + fail: + grub_free (memory_map); + return 0; +} + +GRUB_MOD_INIT(memmap) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("memmap", grub_cmd_memmap, GRUB_COMMAND_FLAG_BOTH, + "memmap", + "Display memory map.", NULL); +} + +GRUB_MOD_FINI(memmap) +{ + grub_unregister_command ("memmap"); +} diff --git a/commands/efi/systab.c b/commands/efi/systab.c new file mode 100644 index 000000000..1d90ca9ca --- /dev/null +++ b/commands/efi/systab.c @@ -0,0 +1,258 @@ +/* systab.c - Display EFI systab. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ +#include +#include +#include +#include +#include +#include + +#define ACPI_20_TABLE_GUID \ +{0x8868e871,0xe4f1,0x11d3,{0xbc,0x22,0x0,0x80,0xc7,0x3c,0x88,0x81}} +#define ACPI_TABLE_GUID \ +{0xeb9d2d30,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}} +#define SAL_SYSTEM_TABLE_GUID \ +{0xeb9d2d32,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}} +#define SMBIOS_TABLE_GUID \ +{0xeb9d2d31,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}} +#define MPS_TABLE_GUID \ +{0xeb9d2d2f,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}} +#define HCDP_TABLE_GUID \ +{0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}} + +struct guid_mapping +{ + grub_efi_guid_t guid; + const char *name; + void (*disp)(struct guid_mapping *map, void *table); +}; + +static void disp_sal (struct guid_mapping *map, void *table); +static void disp_acpi (struct guid_mapping *map, void *table); + +static const struct guid_mapping guid_mappings[] = + { + { ACPI_20_TABLE_GUID, "ACPI-2.0", disp_acpi}, + { ACPI_TABLE_GUID, "ACPI-1.0", disp_acpi}, + { SAL_SYSTEM_TABLE_GUID, "SAL", disp_sal}, + { SMBIOS_TABLE_GUID, "SMBIOS",NULL}, + { MPS_TABLE_GUID, "MPS", NULL}, + { HCDP_TABLE_GUID, "HCDP", NULL} + }; + +struct sal_system_table +{ + grub_uint32_t signature; + grub_uint32_t total_table_len; + grub_uint16_t sal_rev; + grub_uint16_t entry_count; + grub_uint8_t checksum; + grub_uint8_t reserved1[7]; + grub_uint16_t sal_a_version; + grub_uint16_t sal_b_version; + grub_uint8_t oem_id[32]; + grub_uint8_t product_id[32]; + grub_uint8_t reserved2[8]; +}; + +static void +disp_sal (struct guid_mapping *map, void *table) +{ + struct sal_system_table *t = table; + grub_uint8_t *desc = table; + grub_uint32_t len, l; + + grub_printf ("SAL rev: %02x, signature: %x, len:%x\n", + t->sal_rev, t->signature, t->total_table_len); + grub_printf ("nbr entry: %d, chksum: %02x, SAL version A: %02x B: %02x\n", + t->entry_count, t->checksum, + t->sal_a_version, t->sal_b_version); + grub_printf ("OEM-ID: %-32s\n", t->oem_id); + grub_printf ("Product-ID: %-32s\n", t->product_id); + + desc += sizeof (struct sal_system_table); + len = t->total_table_len - sizeof (struct sal_system_table); + while (len > 0) + { + switch (*desc) + { + case 0: + l = 48; + grub_printf (" Entry point: PAL=%016lx SAL=%016lx GP=%016lx\n", + *(grub_uint64_t*)(desc + 8), + *(grub_uint64_t*)(desc + 16), + *(grub_uint64_t*)(desc + 24)); + break; + case 1: + l = 32; + grub_printf (" Memory descriptor entry addr=%016llx len=%uKB\n", + *(grub_uint64_t*)(desc + 8), + *(grub_uint32_t*)(desc + 16) * 4); + grub_printf (" sal_used=%d attr=%x AR=%x attr_mask=%x " + "type=%x usage=%x\n", + desc[1], desc[2], desc[3], desc[4], desc[5], desc[6]); + break; + case 2: + l = 16; + grub_printf (" Platform features: %02x", desc[1]); + if (desc[1] & 0x01) + grub_printf (" BusLock"); + if (desc[1] & 0x02) + grub_printf (" IrqRedirect"); + if (desc[1] & 0x04) + grub_printf (" IPIRedirect"); + grub_printf ("\n"); + break; + case 3: + l = 32; + grub_printf (" TR type=%d num=%d va=%016llx pte=%016llx\n", + desc[1], desc[2], + *(grub_uint64_t *)(desc + 8), + *(grub_uint64_t *)(desc + 16)); + break; + case 4: + l = 16; + grub_printf (" PTC coherence nbr=%d addr=%016llx\n", + desc[1], *(grub_uint64_t *)(desc + 8)); + break; + case 5: + l = 16; + grub_printf (" AP wake-up: mec=%d vect=%x\n", + desc[1], *(grub_uint64_t *)(desc + 8)); + break; + default: + grub_printf (" unknown entry %d\n", *desc); + return; + } + desc += l; + len -= l; + } +} + +static void +disp_acpi (struct guid_mapping *map, void *table) +{ + disp_acpi_rsdp_table (table); +} + +static void +disp_systab (void) +{ + grub_efi_char16_t *vendor; + const grub_efi_system_table_t *st = grub_efi_system_table; + grub_efi_configuration_table_t *t; + unsigned int i; + + grub_printf ("Signature: %016llx revision: %08x\n", + st->hdr.signature, st->hdr.revision); + grub_printf ("Vendor: "); + for (vendor = st->firmware_vendor; *vendor; vendor++) + grub_printf ("%c", *vendor); + grub_printf (", Version=%x\n", st->firmware_revision); + + grub_printf ("%ld tables:\n", st->num_table_entries); + t = st->configuration_table; + for (i = 0; i < st->num_table_entries; i++) + { + unsigned int j; + + grub_printf ("%016llx ", (grub_uint64_t)t->vendor_table); + + grub_printf ("%08x-%04x-%04x-", + t->vendor_guid.data1, t->vendor_guid.data2, + t->vendor_guid.data3); + for (j = 0; j < 8; j++) + grub_printf ("%02x", t->vendor_guid.data4[j]); + + for (j = 0; j < sizeof (guid_mappings)/sizeof(guid_mappings[0]); j++) + if (grub_memcmp (&guid_mappings[j].guid, &t->vendor_guid, + sizeof (grub_efi_guid_t)) == 0) + grub_printf (" %s", guid_mappings[j].name); + + grub_printf ("\n"); + t++; + } +} + +static void +disp_systab_entry (const char *name) +{ + const grub_efi_system_table_t *st = grub_efi_system_table; + grub_efi_configuration_table_t *t; + unsigned int i; + struct guid_mapping *map; + + map = NULL; + for (i = 0; i < sizeof (guid_mappings)/sizeof(guid_mappings[0]); i++) + if (grub_strcmp (guid_mappings[i].name, name) == 0) + { + map = &guid_mappings[i]; + break; + } + if (map == NULL) + { + grub_printf ("System table '%s' unknown\n", name); + return; + } + if (map->disp == NULL) + { + grub_printf ("Don't know how to display table '%s'\n", name); + return; + } + t = st->configuration_table; + for (i = 0; i < st->num_table_entries; i++) + { + if (grub_memcmp (&map->guid, &t->vendor_guid, + sizeof (grub_efi_guid_t)) == 0) + { + grub_set_more (1); + (*map->disp)(map, t->vendor_table); + grub_set_more (0); + return; + } + t++; + } + grub_printf ("Systab '%s' not found\n", map->name); +} + +static grub_err_t +grub_cmd_systab (struct grub_arg_list *state, int argc, char **args) +{ + int i; + + if (argc == 0) + disp_systab (); + else + for (i = 0; i < argc; i++) + disp_systab_entry (args[i]); + return 0; +} + +GRUB_MOD_INIT(systab) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("systab", grub_cmd_systab, GRUB_COMMAND_FLAG_BOTH, + "systab [NAME]", + "Display EFI system table.", NULL); +} + +GRUB_MOD_FINI(systab) +{ + grub_unregister_command ("systab"); +} diff --git a/conf/ia64-efi.rmk b/conf/ia64-efi.rmk new file mode 100644 index 000000000..ce72d14c0 --- /dev/null +++ b/conf/ia64-efi.rmk @@ -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 --git a/configure.ac b/configure.ac index b3f73e0bd..895b5ffc3 100644 --- a/configure.ac +++ b/configure.ac @@ -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 --git a/geninit.sh b/geninit.sh index 43d2d1640..31a6d660b 100644 --- a/geninit.sh +++ b/geninit.sh @@ -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 --git a/genmk.rb b/genmk.rb index 43dbeacf5..e4abd56d5 100644 --- a/genmk.rb +++ b/genmk.rb @@ -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 --git a/include/grub/dl.h b/include/grub/dl.h index b630c6fcd..017846d79 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -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 --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index fbc6be985..c45cbed02 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -42,6 +42,13 @@ EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, 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 --git a/include/grub/ia64/efi/kernel.h b/include/grub/ia64/efi/kernel.h new file mode 100644 index 000000000..c0549f41a --- /dev/null +++ b/include/grub/ia64/efi/kernel.h @@ -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 . + */ + +#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 --git a/include/grub/ia64/efi/loader.h b/include/grub/ia64/efi/loader.h new file mode 100644 index 000000000..623ae5c49 --- /dev/null +++ b/include/grub/ia64/efi/loader.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +/* It is necessary to export these functions, because normal mode commands + reuse rescue mode commands. */ +void grub_rescue_cmd_linux (int argc, char *argv[]); +void grub_rescue_cmd_initrd (int argc, char *argv[]); +void grub_rescue_cmd_module (int argc, char *argv[]); +void grub_rescue_cmd_relocate (int argc, char *argv[]); +void grub_rescue_cmd_fpswa (int argc, char *argv[]); + +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/ia64/efi/misc.h b/include/grub/ia64/efi/misc.h new file mode 100644 index 000000000..2037f7c24 --- /dev/null +++ b/include/grub/ia64/efi/misc.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +void EXPORT_FUNC (memset) (void); +void EXPORT_FUNC (__ia64_trampoline) (void); +void EXPORT_FUNC (grub_init_modules) (void); + +extern unsigned long EXPORT_VAR (__gp); + diff --git a/include/grub/ia64/efi/time.h b/include/grub/ia64/efi/time.h new file mode 100644 index 000000000..897ce9c00 --- /dev/null +++ b/include/grub/ia64/efi/time.h @@ -0,0 +1,23 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ +#ifndef GRUB_MACHINE_TIME_HEADER +#define GRUB_MACHINE_TIME_HEADER 1 + +#include + +#endif /* ! GRUB_MACHINE_TIME_HEADER */ diff --git a/include/grub/ia64/setjmp.h b/include/grub/ia64/setjmp.h new file mode 100644 index 000000000..c3b2d3be7 --- /dev/null +++ b/include/grub/ia64/setjmp.h @@ -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 . + + 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 --git a/include/grub/ia64/time.h b/include/grub/ia64/time.h new file mode 100644 index 000000000..5db7ff4f1 --- /dev/null +++ b/include/grub/ia64/time.h @@ -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 . + */ + +#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 --git a/include/grub/ia64/types.h b/include/grub/ia64/types.h new file mode 100644 index 000000000..91a546dd2 --- /dev/null +++ b/include/grub/ia64/types.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 8 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 8 + +/* ia64 is little-endian (usually). */ +#undef GRUB_TARGET_WORDS_BIGENDIAN + + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 4a4e2cc41..b1b8f5930 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -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 --git a/kern/dl.c b/kern/dl.c index 9e8c24aba..c6c6f00ec 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -579,6 +579,29 @@ grub_dl_load_core (void *addr, grub_size_t 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 --git a/kern/efi/mm.c b/kern/efi/mm.c index 9cd096d7d..6e55e3655 100644 --- a/kern/efi/mm.c +++ b/kern/efi/mm.c @@ -22,16 +22,14 @@ #include #include +//#define DEBUG_MM + #define NEXT_MEMORY_DESCRIPTOR(desc, size) \ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) -#define BYTES_TO_PAGES(bytes) ((bytes) >> 12) +#define BYTES_TO_PAGES(bytes) ((bytes + 0xfff) >> 12) #define PAGES_TO_BYTES(pages) ((pages) << 12) -/* The size of a memory map obtained from the firmware. This must be - a multiplier of 4KB. */ -#define MEMORY_MAP_SIZE 0x1000 - /* Maintain the list of allocated pages. */ struct allocated_page { @@ -49,11 +47,10 @@ static struct allocated_page *allocated_pages = 0; #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_physical_address_t address, { /* 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_address_t address, 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_descriptor_t *memory_map, 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_descriptor_t *memory_map, 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 --git a/kern/ia64/efi/elf_ia64_efi.lds b/kern/ia64/efi/elf_ia64_efi.lds new file mode 100644 index 000000000..b6889d4af --- /dev/null +++ b/kern/ia64/efi/elf_ia64_efi.lds @@ -0,0 +1,84 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ +OUTPUT_FORMAT("elf64-ia64-little") +OUTPUT_ARCH(ia64) +ENTRY(_start) +SECTIONS +{ + . = 0x240; + .text : + { + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + /* Reserve space for the entry point descriptor. */ + . = ALIGN(16); + QUAD(0) + QUAD(0) + } + . = ALIGN(0x20); + .got : + { + *(.got.plt) + *(.got) + . = ALIGN(0x10); + } + .opd : + { + *(.opd) + } + .sdata : + { + *(.srodata) + *(.sdata) + *(.sbss) + *(.scommon) + . = ALIGN(0x10); + } + .data : + { + *(.data*) + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(0x10); + } + .dynamic : { *(.dynamic) } + + . = ALIGN(4096); + .interp : { *(.interp) } + .plt : { *(.plt) } + .rela : + { + *(.rela.text*) + *(.rela.data*) + *(.rela.sdata) + *(.rela.got) + } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + /DISCARD/ : + { + *(.IA_64.unwind*) + *(.IA64.unwind*) + *(.moddeps) + *(.modname) + } +} diff --git a/kern/ia64/efi/init.c b/kern/ia64/efi/init.c new file mode 100644 index 000000000..c85ef6c42 --- /dev/null +++ b/kern/ia64/efi/init.c @@ -0,0 +1,59 @@ +/* init.c - initialize an ia64-based EFI system */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void +grub_machine_init (void) +{ + grub_efi_init (); + grub_init_modules (); +} + +void +grub_machine_fini (void) +{ + grub_efi_fini (); +} + +void +grub_machine_set_prefix (void) +{ + grub_efi_set_prefix (); +} + +void +grub_arch_sync_caches (void *address, grub_size_t len) +{ + /* Cache line length is at least 32. */ + grub_uint64_t a = (grub_uint64_t)address & ~0x1f; + + /* Flush data. */ + for (len = (len + 31) & ~0x1f; len > 0; len -= 0x20, a += 0x20) + asm volatile ("fc.i %0" : : "r" (a)); + /* Sync and serialize. Maybe extra. */ + asm volatile (";; sync.i;; srlz.i;;"); +} diff --git a/kern/ia64/efi/startup.S b/kern/ia64/efi/startup.S new file mode 100644 index 000000000..9ba6858d9 --- /dev/null +++ b/kern/ia64/efi/startup.S @@ -0,0 +1,40 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + .text + .psr abi64 + .psr lsb + .lsb + + .global _start + .proc _start +_start: + alloc loc0=ar.pfs,2,4,0,0 + mov loc1=rp + addl 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 --git a/kern/ia64/trampoline.S b/kern/ia64/trampoline.S new file mode 100644 index 000000000..376b7bae0 --- /dev/null +++ b/kern/ia64/trampoline.S @@ -0,0 +1,38 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + .text + .psr abi64 + .psr lsb + .lsb + + .proc __ia64_trampoline + .global __ia64_trampoline +__ia64_trampoline: + // Read address of the real descriptor + ld8 r2=[r1],8 + ;; + // Read chain + ld8 r15=[r1] + // Read pc + ld8 r3=[r2],8 + ;; + // Read gp + ld8 r1=[r2] + mov b6=r3 + br.many b6 + .endp __ia64_trampoline diff --git a/loader/ia64/efi/linux.c b/loader/ia64/efi/linux.c new file mode 100644 index 000000000..04c4638f8 --- /dev/null +++ b/loader/ia64/efi/linux.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* #include */ +#include +#include +#include +#include + +#define ALIGN_MIN (256*1024*1024) + +#define GRUB_ELF_SEARCH 1024 + +#define BOOT_PARAM_SIZE 16384 + +struct ia64_boot_param { + grub_uint64_t command_line; /* physical address of command line. */ + grub_uint64_t efi_systab; /* physical address of EFI system table */ + grub_uint64_t efi_memmap; /* physical address of EFI memory map */ + grub_uint64_t efi_memmap_size; /* size of EFI memory map */ + grub_uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */ + grub_uint32_t efi_memdesc_version; /* memory descriptor version */ + struct { + grub_uint16_t num_cols; /* number of columns on console output dev */ + grub_uint16_t num_rows; /* number of rows on console output device */ + grub_uint16_t orig_x; /* cursor's x position */ + grub_uint16_t orig_y; /* cursor's y position */ + } console_info; + grub_uint64_t fpswa; /* physical address of the fpswa interface */ + grub_uint64_t initrd_start; + grub_uint64_t initrd_size; + grub_uint64_t domain_start; /* boot domain address. */ + grub_uint64_t domain_size; /* how big is the boot domain */ + grub_uint64_t modules_chain; + grub_uint64_t modules_nbr; +}; + +struct ia64_boot_module { + grub_uint64_t mod_start; + grub_uint64_t mod_end; + + /* Module command line */ + grub_uint64_t cmdline; + + grub_uint64_t next; +}; + +typedef struct { + grub_uint32_t revision; + grub_uint32_t reserved; + void *fpswa; +} fpswa_interface_t; +static fpswa_interface_t *fpswa; + +#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +static grub_dl_t my_mod; + +static int loaded; + +/* Kernel base and size. */ +static void *kernel_mem; +static grub_efi_uintn_t kernel_pages; +static grub_uint64_t entry; + +/* Initrd base and size. */ +static void *initrd_mem; +static grub_efi_uintn_t initrd_pages; +static grub_efi_uintn_t initrd_size; + +static struct ia64_boot_param *boot_param; +static grub_efi_uintn_t boot_param_pages; +static struct ia64_boot_module *last_module = NULL; + +/* Can linux kernel be relocated ? */ +#define RELOCATE_OFF 0 /* No. */ +#define RELOCATE_ON 1 /* Yes. */ +#define RELOCATE_FORCE 2 /* Always - used to debug. */ +static int relocate = RELOCATE_OFF; + +static inline grub_size_t +page_align (grub_size_t size) +{ + return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); +} + +static void +query_fpswa (void) +{ + grub_efi_handle_t fpswa_image; + grub_efi_boot_services_t *bs; + grub_efi_status_t status; + grub_efi_uintn_t size; + static const grub_efi_guid_t fpswa_protocol = + { 0xc41b6531, 0x97b9, 0x11d3, + {0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }; + + if (fpswa != NULL) + return; + + size = sizeof(grub_efi_handle_t); + + bs = grub_efi_system_table->boot_services; + status = bs->locate_handle (GRUB_EFI_BY_PROTOCOL, + &fpswa_protocol, + NULL, &size, &fpswa_image); + if (status != GRUB_EFI_SUCCESS) + { + grub_printf("Could not locate FPSWA driver\n"); + return; + } + status = bs->handle_protocol (fpswa_image, &fpswa_protocol, &fpswa); + if (status != GRUB_EFI_SUCCESS) + { + grub_printf ("Fpswa protocol not able find the interface\n"); + return; + } +} + +/* Find the optimal number of pages for the memory map. Is it better to + move this code to efi/mm.c? */ +static grub_efi_uintn_t +find_mmap_size (void) +{ + static grub_efi_uintn_t mmap_size = 0; + + if (mmap_size != 0) + return mmap_size; + + mmap_size = (1 << 12); + while (1) + { + int ret; + grub_efi_memory_descriptor_t *mmap; + grub_efi_uintn_t desc_size; + + mmap = grub_malloc (mmap_size); + if (! mmap) + return 0; + + ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); + grub_free (mmap); + + if (ret < 0) + grub_fatal ("cannot get memory map"); + else if (ret > 0) + break; + + mmap_size += (1 << 12); + } + + /* Increase the size a bit for safety, because GRUB allocates more on + later, and EFI itself may allocate more. */ + mmap_size += (1 << 12); + + return page_align (mmap_size); +} + +static void +free_pages (void) +{ + if (kernel_mem) + { + grub_efi_free_boot_pages ((grub_addr_t) kernel_mem, kernel_pages); + kernel_mem = 0; + } + + if (initrd_mem) + { + grub_efi_free_boot_pages ((grub_addr_t) initrd_mem, initrd_pages); + initrd_mem = 0; + } + + if (boot_param) + { + struct ia64_boot_module *mod; + struct ia64_boot_module *next_mod; + + /* Free modules. */ + mod = (struct ia64_boot_module *)boot_param->modules_chain; + while (mod != 0) + { + next_mod = (struct ia64_boot_module *)mod->next; + + grub_efi_free_boot_pages + (mod->mod_start, page_align (mod->mod_end - mod->mod_start) >> 12); + grub_efi_free_boot_pages ((grub_efi_physical_address_t)mod, 1); + + mod = next_mod; + } + + /* Free bootparam. */ + grub_efi_free_boot_pages ((grub_efi_physical_address_t)boot_param, + boot_param_pages); + boot_param = 0; + } +} + +static void * +allocate_pages (grub_uint64_t align, grub_uint64_t size_pages, + grub_uint64_t nobase) +{ + grub_uint64_t size; + grub_efi_uintn_t desc_size; + grub_efi_memory_descriptor_t *mmap, *mmap_end; + grub_efi_uintn_t mmap_size, tmp_mmap_size; + grub_efi_memory_descriptor_t *desc; + void *mem = NULL; + + size = size_pages << 12; + + mmap_size = find_mmap_size (); + + /* Read the memory map temporarily, to find free space. */ + mmap = grub_malloc (mmap_size); + if (! mmap) + return 0; + + tmp_mmap_size = mmap_size; + if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0) + grub_fatal ("cannot get memory map"); + + mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size); + + /* First, find free pages for the real mode code + and the memory map buffer. */ + for (desc = mmap; + desc < mmap_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + grub_uint64_t start, end; + grub_uint64_t aligned_start; + + if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) + continue; + + start = desc->physical_start; + end = start + (desc->num_pages << 12); + /* Align is a power of 2. */ + aligned_start = (start + align - 1) & ~(align - 1); + if (aligned_start + size > end) + continue; + if (aligned_start == nobase) + aligned_start += align; + if (aligned_start + size > end) + continue; + mem = grub_efi_allocate_pages (aligned_start, size_pages); + if (! mem) + grub_fatal ("cannot allocate pages"); + break; + } + + if (! mem) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory"); + goto fail; + } + + grub_free (mmap); + return mem; + + fail: + grub_free (mmap); + free_pages (); + return 0; +} + +static void +set_boot_param_console (void) +{ + grub_efi_simple_text_output_interface_t *conout; + grub_efi_uintn_t cols, rows; + + conout = grub_efi_system_table->con_out; + if (conout->query_mode (conout, conout->mode->mode, &cols, &rows) + != GRUB_EFI_SUCCESS) + return; + + grub_dprintf("linux", + "Console info: cols=%lu rows=%lu x=%u y=%u\n", + cols, rows, + conout->mode->cursor_column, conout->mode->cursor_row); + + boot_param->console_info.num_cols = cols; + boot_param->console_info.num_rows = rows; + boot_param->console_info.orig_x = conout->mode->cursor_column; + boot_param->console_info.orig_y = conout->mode->cursor_row; +} + +static grub_err_t +grub_linux_boot (void) +{ + grub_efi_uintn_t mmap_size; + grub_efi_uintn_t map_key; + grub_efi_uintn_t desc_size; + grub_efi_uint32_t desc_version; + grub_efi_memory_descriptor_t *mmap_buf; + + /* FPSWA. */ + query_fpswa (); + boot_param->fpswa = (grub_uint64_t)fpswa; + + /* Initrd. */ + boot_param->initrd_start = (grub_uint64_t)initrd_mem; + boot_param->initrd_size = (grub_uint64_t)initrd_size; + + set_boot_param_console (); + + grub_printf ("Jump to %016lx\n", entry); + + grub_machine_fini (); + + /* MDT. + Must be done after grub_machine_fini because map_key is used by + exit_boot_services. */ + mmap_size = find_mmap_size (); + mmap_buf = grub_efi_allocate_boot_pages (0, page_align (mmap_size) >> 12); + if (! mmap_buf) + grub_fatal ("cannot allocate memory map"); + if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key, + &desc_size, &desc_version) <= 0) + grub_fatal ("cannot get memory map"); + + boot_param->efi_memmap = (grub_uint64_t)mmap_buf; + boot_param->efi_memmap_size = mmap_size; + boot_param->efi_memdesc_size = desc_size; + boot_param->efi_memdesc_version = desc_version; + + if (! grub_efi_exit_boot_services (map_key)) + grub_fatal ("cannot exit boot services"); + + /* See you next boot. */ + asm volatile ("mov r28=%1; br.sptk.few %0" :: "b"(entry),"r"(boot_param)); + + /* Never reach here. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_unload (void) +{ + free_pages (); + grub_dl_unref (my_mod); + loaded = 0; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_load_elf64 (grub_file_t file, void *buffer) +{ + Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer; + Elf64_Phdr *phdr; + int i; + grub_uint64_t low_addr; + grub_uint64_t high_addr; + grub_uint64_t align; + grub_uint64_t reloc_offset; + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) + return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class"); + + if (ehdr->e_ident[EI_MAG0] != ELFMAG0 + || ehdr->e_ident[EI_MAG1] != ELFMAG1 + || ehdr->e_ident[EI_MAG2] != ELFMAG2 + || ehdr->e_ident[EI_MAG3] != ELFMAG3 + || ehdr->e_version != EV_CURRENT + || ehdr->e_ident[EI_DATA] != ELFDATA2LSB + || ehdr->e_machine != EM_IA_64) + return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found"); + + if (ehdr->e_type != ET_EXEC) + return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type"); + + /* FIXME: Should we support program headers at strange locations? */ + if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > GRUB_ELF_SEARCH) + return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset"); + + entry = ehdr->e_entry; + + /* Compute low, high and align addresses. */ + low_addr = ~0UL; + high_addr = 0; + align = 0; + for (i = 0; i < ehdr->e_phnum; i++) + { + phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff + + i * ehdr->e_phentsize); + if (phdr->p_type == PT_LOAD) + { + if (phdr->p_paddr < low_addr) + low_addr = phdr->p_paddr; + if (phdr->p_paddr + phdr->p_memsz > high_addr) + high_addr = phdr->p_paddr + phdr->p_memsz; + if (phdr->p_align > align) + align = phdr->p_align; + } + } + + if (align < ALIGN_MIN) + align = ALIGN_MIN; + + if (high_addr == 0) + return grub_error (GRUB_ERR_BAD_OS, "no program entries"); + + kernel_pages = page_align (high_addr - low_addr) >> 12; + + if (relocate != RELOCATE_FORCE) + { + kernel_mem = grub_efi_allocate_boot_pages (low_addr, kernel_pages); + reloc_offset = 0; + } + /* Try to relocate. */ + if (! kernel_mem && relocate != RELOCATE_OFF) + { + kernel_mem = allocate_pages (align, kernel_pages, low_addr); + if (kernel_mem) + { + reloc_offset = kernel_mem - low_addr; + grub_printf (" Relocated at %p (offset=%016llx)\n", + kernel_mem, reloc_offset); + entry += reloc_offset; + } + } + if (! kernel_mem) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "cannot allocate memory for OS"); + + /* Load every loadable segment in memory. */ + for (i = 0; i < ehdr->e_phnum; i++) + { + phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff + + i * ehdr->e_phentsize); + if (phdr->p_type == PT_LOAD) + { + grub_printf (" [paddr=%llx load=%llx memsz=%08llx " + "off=%lx flags=%x]\n", + phdr->p_paddr, phdr->p_paddr + reloc_offset, + phdr->p_memsz, phdr->p_offset, phdr->p_flags); + + if (grub_file_seek (file, phdr->p_offset) == -1) + return grub_error (GRUB_ERR_BAD_OS, + "invalid offset in program header"); + + if (grub_file_read (file, (void *)(phdr->p_paddr + reloc_offset), + phdr->p_filesz) + != (grub_ssize_t) phdr->p_filesz) + return grub_error (GRUB_ERR_BAD_OS, + "couldn't read segment from file"); + + if (phdr->p_filesz < phdr->p_memsz) + grub_memset + ((char *)(phdr->p_paddr + reloc_offset + phdr->p_filesz), + 0, phdr->p_memsz - phdr->p_filesz); + + /* Sync caches if necessary. */ + if (phdr->p_flags & PF_X) + grub_arch_sync_caches + ((void *)(phdr->p_paddr + reloc_offset), phdr->p_memsz); + } + } + loaded = 1; + return 0; +} + +void +grub_rescue_cmd_linux (int argc, char *argv[]) +{ + grub_file_t file = 0; + char buffer[GRUB_ELF_SEARCH]; + char *cmdline, *p; + grub_ssize_t len; + int i; + + grub_dl_ref (my_mod); + + grub_loader_unset (); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); + goto fail; + } + + file = grub_gzfile_open (argv[0], 1); + if (! file) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); + goto fail; + } + + len = grub_file_read (file, buffer, sizeof (buffer)); + if (len < (grub_ssize_t)sizeof (Elf64_Ehdr)) + { + grub_error (GRUB_ERR_BAD_OS, "File too small"); + goto fail; + } + + grub_printf ("Loading linux: %s\n", argv[0]); + + if (grub_load_elf64 (file, buffer)) + goto fail; + + len = sizeof("BOOT_IMAGE=") + 8; + for (i = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + len += sizeof (struct ia64_boot_param) + 256; /* Room for extensions. */ + boot_param_pages = page_align (len) >> 12; + boot_param = grub_efi_allocate_boot_pages (0, boot_param_pages); + if (boot_param == 0) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, + "cannot allocate memory for bootparams"); + goto fail; + } + + grub_memset (boot_param, 0, len); + cmdline = ((char *)(boot_param + 1)) + 256; + + /* Build cmdline. */ + p = grub_stpcpy (cmdline, "BOOT_IMAGE"); + for (i = 0; i < argc; i++) + { + *p++ = ' '; + p = grub_stpcpy (p, argv[i]); + } + cmdline[10] = '='; + + boot_param->command_line = (grub_uint64_t)cmdline; + boot_param->efi_systab = (grub_uint64_t)grub_efi_system_table; + + grub_errno = GRUB_ERR_NONE; + + grub_loader_set (grub_linux_boot, grub_linux_unload, 0); + + fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_efi_free_boot_pages ((grub_efi_physical_address_t)boot_param, + boot_param_pages); + grub_dl_unref (my_mod); + } +} + +void +grub_rescue_cmd_initrd (int argc, char *argv[]) +{ + grub_file_t file = 0; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + goto fail; + } + + if (! loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + goto fail; + } + + file = grub_gzfile_open (argv[0], 1); + if (! file) + goto fail; + + grub_printf ("Loading initrd: %s\n",argv[0]); + + initrd_size = grub_file_size (file); + initrd_pages = (page_align (initrd_size) >> 12); + initrd_mem = grub_efi_allocate_boot_pages (0, initrd_pages); + if (! initrd_mem) + grub_fatal ("cannot allocate pages"); + + grub_printf (" [addr=0x%lx, size=0x%lx]\n", + (grub_uint64_t)initrd_mem, initrd_size); + + if (grub_file_read (file, initrd_mem, initrd_size) + != (grub_ssize_t)initrd_size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + fail: + if (file) + grub_file_close (file); +} + +void +grub_rescue_cmd_module (int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size, len = 0; + char *module = 0, *cmdline = 0, *p; + struct ia64_boot_module *mod = NULL; + int i; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + goto fail; + } + + if (!boot_param) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + "You need to load the multiboot kernel first"); + goto fail; + } + + file = grub_gzfile_open (argv[0], 1); + if (! file) + goto fail; + + size = grub_file_size (file); + module = grub_efi_allocate_boot_pages (0, page_align (size) >> 12); + if (! module) + goto fail; + + grub_printf ("Module %s [addr=%llx + %lx]\n", + argv[0], (grub_uint64_t)module, size); + + if (grub_file_read (file, module, size) != size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + len = sizeof (struct ia64_boot_module); + for (i = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + + if (len > 4096) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "module command line too long"); + goto fail; + } + mod = grub_efi_allocate_boot_pages (0, 1); + if (! mod) + goto fail; + + p = (char *)(mod + 1); + + mod->mod_start = (grub_uint64_t)module; + mod->mod_end = (grub_uint64_t)module + size; + mod->cmdline = (grub_uint64_t)p; + mod->next = 0; + + if (last_module) + last_module->next = (grub_uint64_t)mod; + else + { + last_module = mod; + boot_param->modules_chain = (grub_uint64_t)mod; + } + boot_param->modules_nbr++; + + /* Copy command line. */ + for (i = 0; i < argc; i++) + { + p = grub_stpcpy (p, argv[i]); + *(p++) = ' '; + } + + /* Remove the space after the last word. */ + *(--p) = '\0'; + + + fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_free (module); + grub_free (cmdline); + } +} + +void +grub_rescue_cmd_relocate (int argc, char *argv[]) +{ + static const char * const vals[] = { "off", "on", "force"}; + unsigned int i; + + if (argc == 0) + { + grub_printf ("relocate is %s\n", vals[relocate]); + } + else if (argc == 1) + { + if (kernel_mem != NULL) + grub_printf ("Warning: kernel already loaded!\n"); + for (i = 0; i < sizeof (vals)/sizeof(vals[0]); i++) + if (grub_strcmp (argv[0], vals[i]) == 0) + { + relocate = i; + return; + } + grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown relocate value"); + } + else + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "accept 0 or 1 argument"); + } +} + + +void +grub_rescue_cmd_fpswa (int argc, char *argv[] __attribute__((unused))) +{ + if (argc != 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Arguments not expected"); + return; + } + query_fpswa (); + if (fpswa == NULL) + grub_printf ("No FPSWA loaded\n"); + else + grub_printf ("FPSWA revision: %x\n", fpswa->revision); +} + +GRUB_MOD_INIT(linux) +{ + grub_rescue_register_command ("linux", + grub_rescue_cmd_linux, + "load linux"); + grub_rescue_register_command ("initrd", + grub_rescue_cmd_initrd, + "load initrd"); + grub_rescue_register_command ("module", grub_rescue_cmd_module, + "load a multiboot module"); + grub_rescue_register_command ("relocate", grub_rescue_cmd_relocate, + "set relocate feature"); + grub_rescue_register_command ("fpswa", grub_rescue_cmd_fpswa, + "load fpswa"); + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_rescue_unregister_command ("linux"); + grub_rescue_unregister_command ("initrd"); + grub_rescue_unregister_command ("module"); + grub_rescue_unregister_command ("relocate"); + grub_rescue_unregister_command ("fpswa"); +} diff --git a/loader/ia64/efi/linux_normal.c b/loader/ia64/efi/linux_normal.c new file mode 100644 index 000000000..3a567b09f --- /dev/null +++ b/loader/ia64/efi/linux_normal.c @@ -0,0 +1,107 @@ +/* linux_normal.c - boot linux */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_err_t +grub_normal_linux_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_linux (argc, args); + return grub_errno; +} + + +static grub_err_t +grub_normal_initrd_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_initrd (argc, args); + return grub_errno; +} + +static grub_err_t +grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_module (argc, args); + return grub_errno; +} + +static grub_err_t +grub_normal_cmd_relocate (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_relocate (argc, args); + return grub_errno; +} + +static grub_err_t +grub_normal_cmd_fpswa (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_fpswa (argc, args); + return grub_errno; +} + +GRUB_MOD_INIT(linux_normal) +{ + (void) mod; /* To stop warning. */ + grub_register_command + ("linux", grub_normal_linux_command, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "linux FILE [ARGS...]", + "Load a linux kernel.", 0); + + grub_register_command + ("initrd", grub_normal_initrd_command, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "initrd FILE", + "Load an initrd.", 0); + + grub_register_command + ("module", grub_normal_cmd_module, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "module FILE [ARGS...]", + "Load a Multiboot module.", 0); + + grub_register_command + ("relocate", grub_normal_cmd_relocate, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "relocate [on|off|force]", + "Set relocate feature.", 0); + + grub_register_command + ("fpswa", grub_normal_cmd_fpswa, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "fpswa", + "Display FPSWA version.", 0); +} + +GRUB_MOD_FINI(linux_normal) +{ + grub_unregister_command ("linux"); + grub_unregister_command ("initrd"); + grub_unregister_command ("normal"); + grub_unregister_command ("relocate"); + grub_unregister_command ("fpswa"); +} diff --git a/normal/ia64/longjmp.S b/normal/ia64/longjmp.S new file mode 100644 index 000000000..23dec8687 --- /dev/null +++ b/normal/ia64/longjmp.S @@ -0,0 +1,162 @@ +/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by David Mosberger-Tang . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + Note that __sigsetjmp() did NOT flush the register stack. Instead, + we do it here since __longjmp() is usually much less frequently + invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp() + didn't (and wouldn't be able to) save ar.rnat either. This is a problem + because if we're not careful, we could end up loading random NaT bits. + There are two cases: + + (i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp) + ar.rnat contains the desired bits---preserve ar.rnat + across loadrs and write to ar.bspstore + + (ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp) + The desired ar.rnat is stored in + ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those + bits into ar.rnat after setting ar.bspstore. */ + + + +# define pPos p6 /* is rotate count positive? */ +# define pNeg p7 /* is rotate count negative? */ + + + /* __longjmp(__jmp_buf buf, int val) */ + + .text + .global longjmp + .proc longjmp +longjmp: + alloc r8=ar.pfs,2,1,0,0 + mov r27=ar.rsc + add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr + ;; + ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr + mov r10=ar.bsp + and r11=~0x3,r27 // clear ar.rsc.mode + ;; + flushrs // flush dirty regs to backing store (must be first in insn grp) + ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp + sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf + ;; + ld8 r25=[r2] // r25 <- jmpbuf.ar_unat + extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f + ;; + cmp.lt pNeg,pPos=r8,r0 + mov r2=in0 + ;; +(pPos) mov r16=r8 +(pNeg) add r16=64,r8 +(pPos) sub r17=64,r8 +(pNeg) sub r17=r0,r8 + ;; + mov ar.rsc=r11 // put RSE in enforced lazy mode + shr.u r8=r25,r16 + add r3=8,in0 // r3 <- &jmpbuf.r1 + shl r9=r25,r17 + ;; + or r25=r8,r9 + ;; + mov r26=ar.rnat + mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12) + ;; + ld8.fill.nta sp=[r2],16 // r12 (sp) + ld8.fill.nta gp=[r3],16 // r1 (gp) + dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp) + ;; + ld8.nta r16=[r2],16 // caller's unat + ld8.nta r17=[r3],16 // fpsr + ;; + ld8.fill.nta r4=[r2],16 // r4 + ld8.fill.nta r5=[r3],16 // r5 (gp) + cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp) + ;; + ld8.fill.nta r6=[r2],16 // r6 + ld8.fill.nta r7=[r3],16 // r7 + ;; + mov ar.unat=r16 // restore caller's unat + mov ar.fpsr=r17 // restore fpsr + ;; + ld8.nta r16=[r2],16 // b0 + ld8.nta r17=[r3],16 // b1 + ;; +(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp) + mov ar.bspstore=r23 // restore ar.bspstore + ;; + ld8.nta r18=[r2],16 // b2 + ld8.nta r19=[r3],16 // b3 + ;; + ld8.nta r20=[r2],16 // b4 + ld8.nta r21=[r3],16 // b5 + ;; + ld8.nta r11=[r2],16 // ar.pfs + ld8.nta r22=[r3],56 // ar.lc + ;; + ld8.nta r24=[r2],32 // pr + mov b0=r16 + ;; + ldf.fill.nta f2=[r2],32 + ldf.fill.nta f3=[r3],32 + mov b1=r17 + ;; + ldf.fill.nta f4=[r2],32 + ldf.fill.nta f5=[r3],32 + mov b2=r18 + ;; + ldf.fill.nta f16=[r2],32 + ldf.fill.nta f17=[r3],32 + mov b3=r19 + ;; + ldf.fill.nta f18=[r2],32 + ldf.fill.nta f19=[r3],32 + mov b4=r20 + ;; + ldf.fill.nta f20=[r2],32 + ldf.fill.nta f21=[r3],32 + mov b5=r21 + ;; + ldf.fill.nta f22=[r2],32 + ldf.fill.nta f23=[r3],32 + mov ar.lc=r22 + ;; + ldf.fill.nta f24=[r2],32 + ldf.fill.nta f25=[r3],32 + cmp.eq p8,p9=0,in1 + ;; + ldf.fill.nta f26=[r2],32 + ldf.fill.nta f27=[r3],32 + mov ar.pfs=r11 + ;; + ldf.fill.nta f28=[r2],32 + ldf.fill.nta f29=[r3],32 + ;; + ldf.fill.nta f30=[r2] + ldf.fill.nta f31=[r3] +(p8) mov r8=1 + + mov ar.rnat=r26 // restore ar.rnat + ;; + mov ar.rsc=r27 // restore ar.rsc +(p9) mov r8=in1 + + invala // virt. -> phys. regnum mapping may change + mov pr=r24,-1 + br.ret.dptk.few rp + .endp longjmp diff --git a/normal/ia64/setjmp.S b/normal/ia64/setjmp.S new file mode 100644 index 000000000..4bc2103b7 --- /dev/null +++ b/normal/ia64/setjmp.S @@ -0,0 +1,171 @@ +/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by David Mosberger-Tang . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + The layout of the jmp_buf is as follows. This is subject to change + and user-code should never depend on the particular layout of + jmp_buf! + + + offset: description: + ------- ------------ + 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS) + 0x008 r1 (gp) + 0x010 caller's unat + 0x018 fpsr + 0x020 r4 + 0x028 r5 + 0x030 r6 + 0x038 r7 + 0x040 rp (b0) + 0x048 b1 + 0x050 b2 + 0x058 b3 + 0x060 b4 + 0x068 b5 + 0x070 ar.pfs + 0x078 ar.lc + 0x080 pr + 0x088 ar.bsp ; unchangeable (see __longjmp.S) + 0x090 ar.unat + 0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat) + 0x0a0 f2 + 0x0b0 f3 + 0x0c0 f4 + 0x0d0 f5 + 0x0e0 f16 + 0x0f0 f17 + 0x100 f18 + 0x110 f19 + 0x120 f20 + 0x130 f21 + 0x130 f22 + 0x140 f23 + 0x150 f24 + 0x160 f25 + 0x170 f26 + 0x180 f27 + 0x190 f28 + 0x1a0 f29 + 0x1b0 f30 + 0x1c0 f31 */ + + + /* The following two entry points are the traditional entry points: */ + + .text + .global setjmp + .proc setjmp +setjmp: + alloc r8=ar.pfs,2,0,0,0 + mov in1=1 + br.cond.sptk.many __sigsetjmp + .endp setjmp + + /* __sigsetjmp(__jmp_buf buf, int savemask) */ + + .proc __sigsetjmp +__sigsetjmp: + //.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) + alloc loc1=ar.pfs,2,2,2,0 + mov r16=ar.unat + ;; + mov r17=ar.fpsr + mov r2=in0 + add r3=8,in0 + ;; + st8.spill.nta [r2]=sp,16 // r12 (sp) + st8.spill.nta [r3]=gp,16 // r1 (gp) + ;; + st8.nta [r2]=r16,16 // save caller's unat + st8.nta [r3]=r17,16 // save fpsr + add r8=0xa0,in0 + ;; + st8.spill.nta [r2]=r4,16 // r4 + st8.spill.nta [r3]=r5,16 // r5 + add r9=0xb0,in0 + ;; + stf.spill.nta [r8]=f2,32 + stf.spill.nta [r9]=f3,32 + mov loc0=rp + .body + ;; + stf.spill.nta [r8]=f4,32 + stf.spill.nta [r9]=f5,32 + mov r17=b1 + ;; + stf.spill.nta [r8]=f16,32 + stf.spill.nta [r9]=f17,32 + mov r18=b2 + ;; + stf.spill.nta [r8]=f18,32 + stf.spill.nta [r9]=f19,32 + mov r19=b3 + ;; + stf.spill.nta [r8]=f20,32 + stf.spill.nta [r9]=f21,32 + mov r20=b4 + ;; + stf.spill.nta [r8]=f22,32 + stf.spill.nta [r9]=f23,32 + mov r21=b5 + ;; + stf.spill.nta [r8]=f24,32 + stf.spill.nta [r9]=f25,32 + mov r22=ar.lc + ;; + stf.spill.nta [r8]=f26,32 + stf.spill.nta [r9]=f27,32 + mov r24=pr + ;; + stf.spill.nta [r8]=f28,32 + stf.spill.nta [r9]=f29,32 + ;; + stf.spill.nta [r8]=f30 + stf.spill.nta [r9]=f31 + + st8.spill.nta [r2]=r6,16 // r6 + st8.spill.nta [r3]=r7,16 // r7 + ;; + mov r23=ar.bsp + mov r25=ar.unat + mov out0=in0 + + st8.nta [r2]=loc0,16 // b0 + st8.nta [r3]=r17,16 // b1 + mov out1=in1 + ;; + st8.nta [r2]=r18,16 // b2 + st8.nta [r3]=r19,16 // b3 + ;; + st8.nta [r2]=r20,16 // b4 + st8.nta [r3]=r21,16 // b5 + ;; + st8.nta [r2]=loc1,16 // ar.pfs + st8.nta [r3]=r22,16 // ar.lc + ;; + st8.nta [r2]=r24,16 // pr + st8.nta [r3]=r23,16 // ar.bsp + ;; + st8.nta [r2]=r25 // ar.unat + st8.nta [r3]=in0 // &__jmp_buf + mov r8=0 + mov rp=loc0 + mov ar.pfs=loc1 + br.ret.sptk.many rp + + .endp __sigsetjmp diff --git a/util/ia64/efi/elf2pe.c b/util/ia64/efi/elf2pe.c new file mode 100644 index 000000000..23687fe68 --- /dev/null +++ b/util/ia64/efi/elf2pe.c @@ -0,0 +1,812 @@ +/* elf2pe.c - convert elf binary to PE/Coff. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ +#include +#include +#include +#include +#include +#include + +#if defined(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 --git a/util/ia64/efi/grub-install.in b/util/ia64/efi/grub-install.in new file mode 100644 index 000000000..63b0c9f6c --- /dev/null +++ b/util/ia64/efi/grub-install.in @@ -0,0 +1,233 @@ +#! /bin/sh + +# Install GRUB on your EFI partition. +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + + +# Initialize some variables. +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 +} + +# 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 --git a/util/ia64/efi/pe32.h b/util/ia64/efi/pe32.h new file mode 100644 index 000000000..391e70c26 --- /dev/null +++ b/util/ia64/efi/pe32.h @@ -0,0 +1,237 @@ +/* pe32.h - PE/Coff definitions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ +#ifdef USE_PE32PLUS +typedef uint64_t pe32_uintptr_t; +#else +typedef uint32_t pe32_uintptr_t; +#endif + +struct pe32_coff_header +{ + uint16_t machine; + uint16_t num_sections; + uint32_t time; + uint32_t symtab_offset; + uint32_t num_symbols; + uint16_t optional_header_size; + uint16_t characteristics; +}; + +#define PE32_MACHINE_I386 0x014c +#define PE32_MACHINE_IA64 0x0200 +#define PE32_MACHINE_EBC 0x0EBC +#define PE32_MACHINE_X64 0x8664 + +#define PE32_RELOCS_STRIPPED 0x0001 +#define PE32_EXECUTABLE_IMAGE 0x0002 +#define PE32_LINE_NUMS_STRIPPED 0x0004 +#define PE32_LOCAL_SYMS_STRIPPED 0x0008 +#define PE32_AGGRESSIVE_WS_TRIM 0x0010 +#define PE32_LARGE_ADDRESS_AWARE 0x0020 +#define PE32_16BIT_MACHINE 0x0040 +#define PE32_BYTES_REVERSED_LO 0x0080 +#define PE32_32BIT_MACHINE 0x0100 +#define PE32_DEBUG_STRIPPED 0x0200 +#define PE32_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define PE32_SYSTEM 0x1000 +#define PE32_DLL 0x2000 +#define PE32_UP_SYSTEM_ONLY 0x4000 +#define PE32_BYTES_REVERSED_HI 0x8000 + +struct pe32_data_directory +{ + uint32_t rva; + uint32_t size; +}; + +struct pe32_optional_header +{ + uint16_t magic; + uint8_t major_linker_version; + uint8_t minor_linker_version; + uint32_t code_size; + uint32_t data_size; + uint32_t bss_size; + uint32_t entry_addr; + uint32_t code_base; + +#ifndef USE_PE32PLUS + uint32_t data_base; +#endif + + pe32_uintptr_t image_base; + uint32_t section_alignment; + uint32_t file_alignment; + uint16_t major_os_version; + uint16_t minor_os_version; + uint16_t major_image_version; + uint16_t minor_image_version; + uint16_t major_subsystem_version; + uint16_t minor_subsystem_version; + uint32_t reserved; + uint32_t image_size; + uint32_t header_size; + uint32_t checksum; + uint16_t subsystem; + uint16_t dll_characteristics; + pe32_uintptr_t stack_reserve_size; + pe32_uintptr_t stack_commit_size; + pe32_uintptr_t heap_reserve_size; + pe32_uintptr_t heap_commit_size; + uint32_t loader_flags; + uint32_t num_data_directories; + + /* Data directories. */ + struct pe32_data_directory export_table; + struct pe32_data_directory import_table; + struct pe32_data_directory resource_table; + struct pe32_data_directory exception_table; + struct pe32_data_directory certificate_table; + struct pe32_data_directory base_relocation_table; + struct pe32_data_directory debug; + struct pe32_data_directory architecture; + struct pe32_data_directory global_ptr; + struct pe32_data_directory tls_table; + struct pe32_data_directory load_config_table; + struct pe32_data_directory bound_import; + struct pe32_data_directory iat; + struct pe32_data_directory delay_import_descriptor; + struct pe32_data_directory com_runtime_header; + struct pe32_data_directory reserved_entry; +}; + +#define PE32_PE32_MAGIC 0x10b +#define PE32_PE64_MAGIC 0x20b + +#define PE32_SUBSYSTEM_EFI_APPLICATION 10 +#define PE32_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define PE32_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define PE32_SUBSYSTEM_EFI_EFI_ROM 13 + +#define PE32_NUM_DATA_DIRECTORIES 16 + +struct pe32_section_header +{ + char name[8]; + uint32_t virtual_size; + uint32_t virtual_address; + uint32_t raw_data_size; + uint32_t raw_data_offset; + uint32_t relocations_offset; + uint32_t line_numbers_offset; + uint16_t num_relocations; + uint16_t num_line_numbers; + uint32_t characteristics; +}; + +#define PE32_SCN_CNT_CODE 0x00000020 +#define PE32_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define PE32_SCN_MEM_DISCARDABLE 0x02000000 +#define PE32_SCN_MEM_EXECUTE 0x20000000 +#define PE32_SCN_MEM_READ 0x40000000 +#define PE32_SCN_MEM_WRITE 0x80000000 + +struct pe32_dos_header +{ + uint16_t magic; // Magic number + uint16_t cblp; // Bytes on last page of file + uint16_t cp; // Pages in file + uint16_t crlc; // Relocations + uint16_t cparhdr; // Size of header in paragraphs + uint16_t minalloc; // Minimum extra paragraphs needed + uint16_t maxalloc; // Maximum extra paragraphs needed + uint16_t ss; // Initial (relative) SS value + uint16_t sp; // Initial SP value + uint16_t csum; // Checksum + uint16_t ip; // Initial IP value + uint16_t cs; // Initial (relative) CS value + uint16_t lfa_rlc; // File address of relocation table + uint16_t ov_no; // Overlay number + uint16_t res[4]; // Reserved words + uint16_t oem_id; // OEM identifier (for e_oeminfo) + uint16_t oem_info; // OEM information; e_oemid specific + uint16_t res2[10]; // Reserved words + uint32_t new_hdr_offset; + + uint16_t stub[0x20]; +}; + +struct pe32_nt_header +{ + /* This is always PE\0\0. */ + char signature[4]; + + /* The COFF file header. */ + struct pe32_coff_header coff_header; + + /* The Optional header. */ + struct pe32_optional_header optional_header; +}; + +struct pe32_base_relocation +{ + uint32_t page_rva; + uint32_t block_size; +}; + +struct pe32_fixup_block +{ + uint32_t page_rva; + uint32_t block_size; + uint16_t entries[0]; +}; + +#define PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset)) + +#define PE32_REL_BASED_ABSOLUTE 0 +#define PE32_REL_BASED_HIGHLOW 3 +#define PE32_REL_BASED_IA64_IMM64 9 +#define PE32_REL_BASED_DIR64 10 + +#define PE32_DEBUG_TYPE_CODEVIEW 2 +struct pe32_debug_directory_entry { + uint32_t characteristics; + uint32_t time; + uint16_t major_version; + uint16_t minor_version; + uint32_t type; + uint32_t data_size; + uint32_t rva; + uint32_t file_offset; +}; + +#define PE32_CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10" +struct pe32_debug_codeview_nb10_entry { + uint32_t signature; // "NB10" + uint32_t unknown[3]; + char filename[0]; /* Filename of .PDB */ +}; + + +#if 1 +#define pe32_check(name, x) extern char pe32_check_##name [x ? 1 : -1] +#ifdef USE_PE32PLUS +#define PE32_HEADER_SIZE 112 +#else +#define PE32_HEADER_SIZE 96 +#endif + +pe32_check(optional_header, sizeof (struct pe32_optional_header) == PE32_HEADER_SIZE + PE32_NUM_DATA_DIRECTORIES * 8); +#endif + From c8298743f3b1caf683789c60c7daf0e00a34b48d Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 14:24:17 +0000 Subject: [PATCH 002/211] Second version of the patch (sent to grub-devel in 2008-01-29) --- ChangeLog.ia64 | 1 - Makefile.in | 7 +++---- commands/efi/acpi.c | 11 ++++------- conf/ia64-efi.rmk | 9 +++++++-- config.h.in | 4 ++-- include/grub/ia64/efi/kernel.h | 2 +- include/grub/ia64/setjmp.h | 2 +- include/grub/ia64/time.h | 2 +- kern/ia64/trampoline.S | 8 ++++---- loader/ia64/efi/linux.c | 12 ++++++++---- loader/ia64/efi/linux_normal.c | 2 +- normal/ia64/longjmp.S | 2 +- normal/ia64/setjmp.S | 2 +- util/ia64/efi/elf2pe.c | 4 ++-- 14 files changed, 36 insertions(+), 32 deletions(-) diff --git a/ChangeLog.ia64 b/ChangeLog.ia64 index 35417bec0..64562fb23 100644 --- a/ChangeLog.ia64 +++ b/ChangeLog.ia64 @@ -3,7 +3,6 @@ * 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. diff --git a/Makefile.in b/Makefile.in index 134505d3c..5e8e07dbb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -83,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 ia64-efi.rmk) +RMKFILES = $(wildcard $(srcdir)/conf/*.rmk) MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES)) PKGLIB = $(pkglib_IMAGES) $(pkglib_MODULES) $(pkglib_PROGRAMS) \ @@ -98,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 --git a/commands/efi/acpi.c b/commands/efi/acpi.c index ea9783f00..e65fa0702 100644 --- a/commands/efi/acpi.c +++ b/commands/efi/acpi.c @@ -1,4 +1,4 @@ -/* acpi.c - Display acpi. */ +/* acpi.c - Display acpi tables. */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2008 Free Software Foundation, Inc. @@ -23,20 +23,17 @@ static grub_uint32_t read16 (grub_uint8_t *p) { - return p[0] | (p[1] << 8); + return grub_le_to_cpu16 (*(grub_uint16_t *)p); } static grub_uint32_t read32 (grub_uint8_t *p) { - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); + return grub_le_to_cpu32 (*(grub_uint32_t *)p); } 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); + return grub_le_to_cpu64 (*(grub_uint64_t *)p); } static void diff --git a/conf/ia64-efi.rmk b/conf/ia64-efi.rmk index ce72d14c0..d65fda6d5 100644 --- a/conf/ia64-efi.rmk +++ b/conf/ia64-efi.rmk @@ -20,6 +20,7 @@ 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 \ @@ -27,8 +28,12 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.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 \ + \ + 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 \ diff --git a/config.h.in b/config.h.in index 1aef2123b..c22d5b12b 100644 --- a/config.h.in +++ b/config.h.in @@ -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 --git a/include/grub/ia64/efi/kernel.h b/include/grub/ia64/efi/kernel.h index c0549f41a..af1a35b51 100644 --- a/include/grub/ia64/efi/kernel.h +++ b/include/grub/ia64/efi/kernel.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2007 Free Software Foundation, Inc. + * 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 diff --git a/include/grub/ia64/setjmp.h b/include/grub/ia64/setjmp.h index c3b2d3be7..7689a73dd 100644 --- a/include/grub/ia64/setjmp.h +++ b/include/grub/ia64/setjmp.h @@ -1,5 +1,5 @@ /* Define the machine-dependent type `jmp_buf'. Linux/IA-64 version. - Copyright (C) 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2008 Free Software Foundation, Inc. Contributed by David Mosberger-Tang . The GNU C Library is free software; you can redistribute it and/or diff --git a/include/grub/ia64/time.h b/include/grub/ia64/time.h index 5db7ff4f1..03ee79fa4 100644 --- a/include/grub/ia64/time.h +++ b/include/grub/ia64/time.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007 Free Software Foundation, Inc. + * 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 diff --git a/kern/ia64/trampoline.S b/kern/ia64/trampoline.S index 376b7bae0..e91991041 100644 --- a/kern/ia64/trampoline.S +++ b/kern/ia64/trampoline.S @@ -23,15 +23,15 @@ .proc __ia64_trampoline .global __ia64_trampoline __ia64_trampoline: - // Read address of the real descriptor + /* Read address of the real descriptor. */ ld8 r2=[r1],8 ;; - // Read chain + /* Read chain. */ ld8 r15=[r1] - // Read pc + /* Read pc. */ ld8 r3=[r2],8 ;; - // Read gp + /* Read gp. */ ld8 r1=[r2] mov b6=r3 br.many b6 diff --git a/loader/ia64/efi/linux.c b/loader/ia64/efi/linux.c index 04c4638f8..47f51c5da 100644 --- a/loader/ia64/efi/linux.c +++ b/loader/ia64/efi/linux.c @@ -39,14 +39,16 @@ #define BOOT_PARAM_SIZE 16384 -struct ia64_boot_param { +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 { + 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 */ @@ -61,7 +63,8 @@ struct ia64_boot_param { grub_uint64_t modules_nbr; }; -struct ia64_boot_module { +struct ia64_boot_module +{ grub_uint64_t mod_start; grub_uint64_t mod_end; @@ -71,7 +74,8 @@ struct ia64_boot_module { grub_uint64_t next; }; -typedef struct { +typedef struct +{ grub_uint32_t revision; grub_uint32_t reserved; void *fpswa; diff --git a/loader/ia64/efi/linux_normal.c b/loader/ia64/efi/linux_normal.c index 3a567b09f..ec18c4b9b 100644 --- a/loader/ia64/efi/linux_normal.c +++ b/loader/ia64/efi/linux_normal.c @@ -101,7 +101,7 @@ GRUB_MOD_FINI(linux_normal) { grub_unregister_command ("linux"); grub_unregister_command ("initrd"); - grub_unregister_command ("normal"); + grub_unregister_command ("module"); grub_unregister_command ("relocate"); grub_unregister_command ("fpswa"); } diff --git a/normal/ia64/longjmp.S b/normal/ia64/longjmp.S index 23dec8687..729bdc76e 100644 --- a/normal/ia64/longjmp.S +++ b/normal/ia64/longjmp.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc. Contributed by David Mosberger-Tang . The GNU C Library is free software; you can redistribute it and/or diff --git a/normal/ia64/setjmp.S b/normal/ia64/setjmp.S index 4bc2103b7..0851885c5 100644 --- a/normal/ia64/setjmp.S +++ b/normal/ia64/setjmp.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc. Contributed by David Mosberger-Tang . The GNU C Library is free software; you can redistribute it and/or diff --git a/util/ia64/efi/elf2pe.c b/util/ia64/efi/elf2pe.c index 23687fe68..2840e3337 100644 --- a/util/ia64/efi/elf2pe.c +++ b/util/ia64/efi/elf2pe.c @@ -23,12 +23,12 @@ #include #include -#if defined(i386) +#if defined(ELF2PE_I386) #define USE_ELF32 #define USE_PE32 #define ELF_MACHINE EM_386 #define EFI_MACHINE PE32_MACHINE_I386 -#elif defined(__ia64__) +#elif defined(ELF2PE_IA64) #define USE_ELF64 #define USE_PE32PLUS #define ELF_MACHINE EM_IA_64 From 45220d832e50f01524abe27892ab4a71619868be Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 14:28:03 +0000 Subject: [PATCH 003/211] Third version of the patch (sent to grub-devel in 2008-01-30) --- include/grub/ia64/efi/loader.h | 2 +- loader/ia64/efi/linux.c | 103 +++++++++++++++++---------------- loader/ia64/efi/linux_normal.c | 12 ++-- util/ia64/efi/elf2pe.c | 20 +++---- 4 files changed, 69 insertions(+), 68 deletions(-) diff --git a/include/grub/ia64/efi/loader.h b/include/grub/ia64/efi/loader.h index 623ae5c49..5471a81b5 100644 --- a/include/grub/ia64/efi/loader.h +++ b/include/grub/ia64/efi/loader.h @@ -23,7 +23,7 @@ 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_payload (int argc, char *argv[]); void grub_rescue_cmd_relocate (int argc, char *argv[]); void grub_rescue_cmd_fpswa (int argc, char *argv[]); diff --git a/loader/ia64/efi/linux.c b/loader/ia64/efi/linux.c index 47f51c5da..031bc20dd 100644 --- a/loader/ia64/efi/linux.c +++ b/loader/ia64/efi/linux.c @@ -27,7 +27,7 @@ #include #include #include -/* #include */ +#include #include #include #include @@ -59,16 +59,16 @@ struct ia64_boot_param 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; + grub_uint64_t payloads_chain; + grub_uint64_t payloads_nbr; }; -struct ia64_boot_module +struct ia64_boot_payload { - grub_uint64_t mod_start; - grub_uint64_t mod_end; + grub_uint64_t start; + grub_uint64_t length; - /* Module command line */ + /* Payload command line */ grub_uint64_t cmdline; grub_uint64_t next; @@ -101,7 +101,7 @@ 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; +static struct ia64_boot_payload *last_payload = NULL; /* Can linux kernel be relocated ? */ #define RELOCATE_OFF 0 /* No. */ @@ -133,14 +133,15 @@ query_fpswa (void) bs = grub_efi_system_table->boot_services; status = bs->locate_handle (GRUB_EFI_BY_PROTOCOL, - &fpswa_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, &fpswa_protocol, &fpswa); + 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"); @@ -204,20 +205,20 @@ free_pages (void) if (boot_param) { - struct ia64_boot_module *mod; - struct ia64_boot_module *next_mod; + struct ia64_boot_payload *payload; + struct ia64_boot_payload *next_payload; - /* Free modules. */ - mod = (struct ia64_boot_module *)boot_param->modules_chain; - while (mod != 0) + /* Free payloads. */ + payload = (struct ia64_boot_payload *)boot_param->payloads_chain; + while (payload != 0) { - next_mod = (struct ia64_boot_module *)mod->next; + next_payload = (struct ia64_boot_payload *)payload->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); + (payload->start, page_align (payload->length) >> 12); + grub_efi_free_boot_pages ((grub_efi_physical_address_t)payload, 1); - mod = next_mod; + payload = next_payload; } /* Free bootparam. */ @@ -446,8 +447,8 @@ grub_load_elf64 (grub_file_t file, void *buffer) 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", + reloc_offset = (grub_uint64_t)kernel_mem - low_addr; + grub_printf (" Relocated at %p (offset=%016lx)\n", kernel_mem, reloc_offset); entry += reloc_offset; } @@ -463,12 +464,12 @@ grub_load_elf64 (grub_file_t file, void *buffer) + i * ehdr->e_phentsize); if (phdr->p_type == PT_LOAD) { - grub_printf (" [paddr=%llx load=%llx memsz=%08llx " + 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) == -1) + if (grub_file_seek (file, phdr->p_offset) == (grub_off_t)-1) return grub_error (GRUB_ERR_BAD_OS, "invalid offset in program header"); @@ -582,7 +583,7 @@ grub_rescue_cmd_initrd (int argc, char *argv[]) if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "No filename specified"); goto fail; } @@ -619,12 +620,12 @@ grub_rescue_cmd_initrd (int argc, char *argv[]) } void -grub_rescue_cmd_module (int argc, char *argv[]) +grub_rescue_cmd_payload (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; + char *base = 0, *cmdline = 0, *p; + struct ia64_boot_payload *payload = NULL; int i; if (argc == 0) @@ -636,7 +637,7 @@ grub_rescue_cmd_module (int argc, char *argv[]) if (!boot_param) { grub_error (GRUB_ERR_BAD_ARGUMENT, - "You need to load the multiboot kernel first"); + "You need to load the kernel first"); goto fail; } @@ -645,47 +646,47 @@ grub_rescue_cmd_module (int argc, char *argv[]) goto fail; size = grub_file_size (file); - module = grub_efi_allocate_boot_pages (0, page_align (size) >> 12); - if (! module) + base = grub_efi_allocate_boot_pages (0, page_align (size) >> 12); + if (! base) goto fail; - grub_printf ("Module %s [addr=%llx + %lx]\n", - argv[0], (grub_uint64_t)module, size); + grub_printf ("Payload %s [addr=%lx + %lx]\n", + argv[0], (grub_uint64_t)base, size); - if (grub_file_read (file, module, size) != 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_module); + 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, "module command line too long"); + grub_error (GRUB_ERR_OUT_OF_RANGE, "payload command line too long"); goto fail; } - mod = grub_efi_allocate_boot_pages (0, 1); - if (! mod) + payload = grub_efi_allocate_boot_pages (0, 1); + if (! payload) goto fail; - p = (char *)(mod + 1); + p = (char *)(payload + 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; + payload->start = (grub_uint64_t)base; + payload->length = size; + payload->cmdline = (grub_uint64_t)p; + payload->next = 0; - if (last_module) - last_module->next = (grub_uint64_t)mod; + if (last_payload) + last_payload->next = (grub_uint64_t)payload; else { - last_module = mod; - boot_param->modules_chain = (grub_uint64_t)mod; + last_payload = payload; + boot_param->payloads_chain = (grub_uint64_t)payload; } - boot_param->modules_nbr++; + boot_param->payloads_nbr++; /* Copy command line. */ for (i = 0; i < argc; i++) @@ -704,7 +705,7 @@ grub_rescue_cmd_module (int argc, char *argv[]) if (grub_errno != GRUB_ERR_NONE) { - grub_free (module); + grub_free (base); grub_free (cmdline); } } @@ -761,8 +762,8 @@ GRUB_MOD_INIT(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 ("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, @@ -774,7 +775,7 @@ GRUB_MOD_FINI(linux) { grub_rescue_unregister_command ("linux"); grub_rescue_unregister_command ("initrd"); - grub_rescue_unregister_command ("module"); + grub_rescue_unregister_command ("payload"); grub_rescue_unregister_command ("relocate"); grub_rescue_unregister_command ("fpswa"); } diff --git a/loader/ia64/efi/linux_normal.c b/loader/ia64/efi/linux_normal.c index ec18c4b9b..b5ddffb0d 100644 --- a/loader/ia64/efi/linux_normal.c +++ b/loader/ia64/efi/linux_normal.c @@ -40,10 +40,10 @@ grub_normal_initrd_command (struct grub_arg_list *state __attribute__ ((unused)) } static grub_err_t -grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)), +grub_normal_cmd_payload (struct grub_arg_list *state __attribute__ ((unused)), int argc, char **args) { - grub_rescue_cmd_module (argc, args); + grub_rescue_cmd_payload (argc, args); return grub_errno; } @@ -79,10 +79,10 @@ GRUB_MOD_INIT(linux_normal) "Load an initrd.", 0); grub_register_command - ("module", grub_normal_cmd_module, + ("payload", grub_normal_cmd_payload, GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, - "module FILE [ARGS...]", - "Load a Multiboot module.", 0); + "payload FILE [ARGS...]", + "Load an additional file.", 0); grub_register_command ("relocate", grub_normal_cmd_relocate, @@ -101,7 +101,7 @@ GRUB_MOD_FINI(linux_normal) { grub_unregister_command ("linux"); grub_unregister_command ("initrd"); - grub_unregister_command ("module"); + grub_unregister_command ("payload"); grub_unregister_command ("relocate"); grub_unregister_command ("fpswa"); } diff --git a/util/ia64/efi/elf2pe.c b/util/ia64/efi/elf2pe.c index 2840e3337..66d28bde8 100644 --- a/util/ia64/efi/elf2pe.c +++ b/util/ia64/efi/elf2pe.c @@ -70,7 +70,7 @@ typedef Elf64_Sym Elf_Sym; #define ELF_R_SYM(r) ELF64_R_SYM(r) #endif -#ifdef __ia64__ +#ifdef ELF2PE_IA64 #define ELF_ETYPE ET_DYN #else #define ELF_ETYPE ET_EXEC @@ -99,7 +99,7 @@ uint32_t text_offset; uint32_t data_offset; uint32_t reloc_offset; -#ifdef __ia64__ +#ifdef ELF2PE_IA64 uint32_t coff_entry_descr_offset; uint32_t coff_entry_descr_func; uint64_t plt_base; @@ -160,7 +160,7 @@ is_text_shdr (Elf_Shdr *shdr) if (shdr->sh_type != SHT_PROGBITS) { return 0; } -#ifdef __ia64__ +#ifdef ELF2PE_IA64 return (shdr->sh_flags & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_ALLOC | SHF_EXECINSTR); #else @@ -229,7 +229,7 @@ scan_sections (void) } coff_sections_offset[i] = coff_offset; coff_offset += shdr->sh_size; -#ifdef __ia64__ +#ifdef ELF2PE_IA64 if (coff_sections_offset[i] != shdr->sh_addr) { fprintf (stderr, "Section %s: Coff offset (%x) != Elf offset (%lx)", @@ -244,7 +244,7 @@ scan_sections (void) shdr_dynamic = shdr; } } -#ifdef __ia64__ +#ifdef ELF2PE_IA64 /* 16 bytes are reserved (by the ld script) for the entry point descriptor. */ coff_entry_descr_offset = coff_offset - 16; @@ -259,7 +259,7 @@ scan_sections (void) if (is_data_shdr (shdr)) { coff_sections_offset[i] = coff_offset; coff_offset += shdr->sh_size; -#ifdef __ia64__ +#ifdef ELF2PE_IA64 if (coff_sections_offset[i] != shdr->sh_addr) { fprintf (stderr, "Section %s: Coff offset (%x) != Elf offset (%lx)", @@ -307,7 +307,7 @@ scan_sections (void) 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__ +#ifdef ELF2PE_IA64 nt_hdr->optional_header.entry_addr = coff_entry_descr_offset; coff_entry_descr_func = coff_entry; #else @@ -335,7 +335,7 @@ scan_sections (void) PE32_SCN_CNT_INITIALIZED_DATA | PE32_SCN_MEM_WRITE | PE32_SCN_MEM_READ); -#ifdef __ia64__ +#ifdef ELF2PE_IA64 if (shdr_dynamic != NULL) { Elf64_Dyn *dyn = (Elf64_Dyn*)((uint8_t*)ehdr + shdr_dynamic->sh_offset); @@ -639,7 +639,7 @@ write_relocations(void) } } -#ifdef __ia64__ +#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 @@ -719,7 +719,7 @@ convert_elf (uint8_t **file_buffer, unsigned int *file_length) if (write_sections (is_text_shdr) != 0) return -3; -#ifdef __ia64__ +#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 From 85312e19336ae0f773b811f1f9f69832d6ef1f75 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 16:14:58 +0000 Subject: [PATCH 004/211] kernel.h adjustments to fix build --- ChangeLog.ia64 | 2 ++ include/grub/ia64/efi/kernel.h | 13 +++++++------ include/grub/ia64/kernel.h | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 include/grub/ia64/kernel.h diff --git a/ChangeLog.ia64 b/ChangeLog.ia64 index 64562fb23..453cbd88c 100644 --- a/ChangeLog.ia64 +++ b/ChangeLog.ia64 @@ -1,4 +1,5 @@ 2008-01-28 Tristan Gingold +2010-01-18 Robert Millan * geninit.sh: Call _init with a null argument. * configure.ac: Add ia64-efi target. @@ -24,6 +25,7 @@ * 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/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. diff --git a/include/grub/ia64/efi/kernel.h b/include/grub/ia64/efi/kernel.h index af1a35b51..ae75380f0 100644 --- a/include/grub/ia64/efi/kernel.h +++ b/include/grub/ia64/efi/kernel.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 2002,2003,2007,2008,2010 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 @@ -19,15 +19,16 @@ #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 */ +#ifndef ASM_FILE +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; +#endif +#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ diff --git a/include/grub/ia64/kernel.h b/include/grub/ia64/kernel.h new file mode 100644 index 000000000..c5496a00b --- /dev/null +++ b/include/grub/ia64/kernel.h @@ -0,0 +1,25 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_KERNEL_HEADER +#define GRUB_CPU_KERNEL_HEADER 1 + +#define GRUB_MOD_ALIGN 0x1 +#define GRUB_MOD_GAP 0x0 + +#endif /* ! GRUB_CPU_KERNEL_HEADER */ From c5565c52925a729ffeb275ff1a848376dd6bd543 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 17:35:27 +0000 Subject: [PATCH 005/211] Rewrite ia64-efi.rmk --- conf/ia64-efi.rmk | 138 ++++++++++++---------------------------------- 1 file changed, 36 insertions(+), 102 deletions(-) diff --git a/conf/ia64-efi.rmk b/conf/ia64-efi.rmk index d65fda6d5..34f028606 100644 --- a/conf/ia64-efi.rmk +++ b/conf/ia64-efi.rmk @@ -2,126 +2,60 @@ COMMON_ASFLAGS = -nostdinc -fno-builtin COMMON_CFLAGS = -fno-builtin -fpic -minline-int-divide-max-throughput -COMMON_LDFLAGS = -melf_64 -nostdlib +COMMON_LDFLAGS = -melf_64 -nostdlib -STRIP_FLAGS=-R .note -R .comment -X +STRIP_FLAGS = -R .note -R .comment -X -# Utilities. -bin_UTILITIES = grub-elf2pe -#sbin_UTILITIES = grub-emu +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h -# Scripts. -sbin_SCRIPTS = grub-install +bin_UTILITIES += grub-elf2pe +grub_elf2pe_SOURCES = util/ia64/efi/elf2pe.c +grub_elf2pe_CFLAGS = -DELF2PE_IA64 -# For grub-install. +sbin_SCRIPTS += 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 +pkglib_MODULES = kernel.img -# 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 \ +kernel_img_EXPORTS = no +kernel_img_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/disk.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/term.c \ + kern/rescue_parser.c kern/rescue_reader.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) + term/efi/console.c disk/efi/efidisk.c \ + kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c \ + commands/boot.c \ + loader/ia64/efi/linux.c \ + commands/halt.c \ + commands/reboot.c \ + commands/efi/memmap.c \ + commands/efi/systab.c \ + commands/efi/acpi2.c +kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ + cache.h ia64/efi/misc.h \ + efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h i18n.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_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 +symlist.c: $(addprefix include/grub/,$(kernel_img_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 +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_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 From 4e9fe6a2940955d0e84e02b058391409e5c00e9d Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 17:36:16 +0000 Subject: [PATCH 006/211] Adjust loader for new command interface. --- loader/ia64/efi/linux.c | 51 ++++++++++------ loader/ia64/efi/linux_normal.c | 107 --------------------------------- 2 files changed, 32 insertions(+), 126 deletions(-) delete mode 100644 loader/ia64/efi/linux_normal.c diff --git a/loader/ia64/efi/linux.c b/loader/ia64/efi/linux.c index 031bc20dd..9020efd28 100644 --- a/loader/ia64/efi/linux.c +++ b/loader/ia64/efi/linux.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008,2010 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 @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -756,26 +756,39 @@ grub_rescue_cmd_fpswa (int argc, char *argv[] __attribute__((unused))) 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"); + grub_register_extcmd ("linux", grub_normal_linux_command, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "linux FILE [ARGS...]", + "Load Linux.", 0); + + grub_register_extcmd ("initrd", grub_normal_initrd_command, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "initrd FILE", + "Load initrd.", 0); + + grub_register_extcmd ("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_extcmd ("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_extcmd ("fpswa", grub_normal_cmd_fpswa, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "fpswa", + "Display FPSWA version.", 0); + 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"); + grub_unregister_command ("linux"); + grub_unregister_command ("initrd"); + grub_unregister_command ("payload"); + grub_unregister_command ("relocate"); + grub_unregister_command ("fpswa"); } diff --git a/loader/ia64/efi/linux_normal.c b/loader/ia64/efi/linux_normal.c deleted file mode 100644 index b5ddffb0d..000000000 --- a/loader/ia64/efi/linux_normal.c +++ /dev/null @@ -1,107 +0,0 @@ -/* linux_normal.c - boot linux */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -static grub_err_t -grub_normal_linux_command (struct grub_arg_list *state __attribute__ ((unused)), - int argc, char **args) -{ - grub_rescue_cmd_linux (argc, args); - return grub_errno; -} - - -static grub_err_t -grub_normal_initrd_command (struct grub_arg_list *state __attribute__ ((unused)), - int argc, char **args) -{ - grub_rescue_cmd_initrd (argc, args); - return grub_errno; -} - -static grub_err_t -grub_normal_cmd_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"); -} From cba4bdc6a3aa122435d5ec7c96192b01ad3efe9a Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 17:36:55 +0000 Subject: [PATCH 007/211] Move normal/ia64 to lib/ia64 --- {normal => lib}/ia64/longjmp.S | 0 {normal => lib}/ia64/setjmp.S | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {normal => lib}/ia64/longjmp.S (100%) rename {normal => lib}/ia64/setjmp.S (100%) diff --git a/normal/ia64/longjmp.S b/lib/ia64/longjmp.S similarity index 100% rename from normal/ia64/longjmp.S rename to lib/ia64/longjmp.S diff --git a/normal/ia64/setjmp.S b/lib/ia64/setjmp.S similarity index 100% rename from normal/ia64/setjmp.S rename to lib/ia64/setjmp.S From 78cd36e08da585214aec7643d0d82b1dc5d643e2 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 17:37:19 +0000 Subject: [PATCH 008/211] Disable grub-mkelfimage. --- conf/common.rmk | 7 ------- 1 file changed, 7 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index ffcdf045c..d97461753 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -11,13 +11,6 @@ else grub_mkdevicemap_SOURCES += util/devicemap.c endif -# For grub-mkelfimage. -bin_UTILITIES += grub-mkelfimage -grub_mkelfimage_SOURCES = gnulib/progname.c \ - util/elf/grub-mkimage.c util/misc.c \ - util/resolve.c -util/elf/grub-mkimage.c_DEPENDENCIES = Makefile - # For grub-probe. sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h From cdefd058dc54e6538a98de6809cf28c729bc7b9e Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 17:37:51 +0000 Subject: [PATCH 009/211] grub_*_init() has no argument. Also add branch-specific "module_" prefix. --- geninit.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/geninit.sh b/geninit.sh index 31a6d660b..15e9c76a6 100644 --- a/geninit.sh +++ b/geninit.sh @@ -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 (0);/' + echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/ grub_module_\1_init ();/' fi done < ${lst} @@ -66,7 +66,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_fini ();/' + echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/ grub_module_\1_fini ();/' fi done < ${lst} From 394ec6b646e72f8831a3d61db15433d1471fcf3f Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 17:38:39 +0000 Subject: [PATCH 010/211] Adjust for new command interface. --- commands/efi/memmap.c | 8 ++++---- commands/efi/systab.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/commands/efi/memmap.c b/commands/efi/memmap.c index a3ce82841..d49e02080 100644 --- a/commands/efi/memmap.c +++ b/commands/efi/memmap.c @@ -132,12 +132,12 @@ grub_cmd_memmap (struct grub_arg_list *state, int argc, char **args) 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_register_extcmd ("memmap", grub_cmd_memmap, GRUB_COMMAND_FLAG_BOTH, + "memmap", + "Display memory map.", NULL); } GRUB_MOD_FINI(memmap) { - grub_unregister_command ("memmap"); + grub_unregister_extcmd ("memmap"); } diff --git a/commands/efi/systab.c b/commands/efi/systab.c index 1d90ca9ca..27a2cde83 100644 --- a/commands/efi/systab.c +++ b/commands/efi/systab.c @@ -246,13 +246,13 @@ grub_cmd_systab (struct grub_arg_list *state, int argc, char **args) 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); + (void) mod; /* To stop warning. */ + grub_register_extcmd ("systab", grub_cmd_systab, GRUB_COMMAND_FLAG_BOTH, + "systab [NAME]", + "Display EFI system table.", NULL); } GRUB_MOD_FINI(systab) { - grub_unregister_command ("systab"); + grub_unregister_extcmd ("systab"); } From d8a7de8d019702c5448e47f2d19db034f73b051b Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 17:39:04 +0000 Subject: [PATCH 011/211] Remove memset() declaration (provided by ) --- include/grub/ia64/efi/misc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/grub/ia64/efi/misc.h b/include/grub/ia64/efi/misc.h index 2037f7c24..2b99dda62 100644 --- a/include/grub/ia64/efi/misc.h +++ b/include/grub/ia64/efi/misc.h @@ -16,7 +16,6 @@ * along with GRUB. If not, see . */ -void EXPORT_FUNC (memset) (void); void EXPORT_FUNC (__ia64_trampoline) (void); void EXPORT_FUNC (grub_init_modules) (void); From e300c41cb28abbfbd6cff98d2cfd3d38d870f3db Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 17:39:35 +0000 Subject: [PATCH 012/211] Disable calls to loadable modules (not supported yet) --- kern/main.c | 4 +++- kern/mm.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/kern/main.c b/kern/main.c index 7250c73e0..8626c256d 100644 --- a/kern/main.c +++ b/kern/main.c @@ -57,6 +57,7 @@ grub_module_iterate (int (*hook) (struct grub_module_header *header)) static void grub_load_modules (void) { +#if 0 auto int hook (struct grub_module_header *); int hook (struct grub_module_header *header) { @@ -72,6 +73,7 @@ grub_load_modules (void) } grub_module_iterate (hook); +#endif } static void @@ -136,7 +138,7 @@ static void grub_load_normal_mode (void) { /* Load the module. */ - grub_dl_load ("normal"); +// grub_dl_load ("normal"); /* Something went wrong. Print errors here to let user know why we're entering rescue mode. */ grub_print_error (); diff --git a/kern/mm.c b/kern/mm.c index ef97b018e..5d008dc4a 100644 --- a/kern/mm.c +++ b/kern/mm.c @@ -330,7 +330,7 @@ grub_memalign (grub_size_t align, grub_size_t size) case 1: /* Unload unneeded modules. */ - grub_dl_unload_unneeded (); +// grub_dl_unload_unneeded (); count++; goto again; From f15f9c5029692d3ff5c4731cde9bc11e1214f7ac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Sep 2010 02:41:21 +0200 Subject: [PATCH 013/211] Remove leftover modules --- grub-core/Makefile.core.def | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 76437f5a5..925f2b7f6 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1425,15 +1425,3 @@ module = { common = commands/efi/memmap.c; enable = ia64_efi; }; - -module = { - name = systab; - common = commands/efi/systab.c; - enable = ia64_efi; -}; - -module = { - name = acpi2; - common = commands/efi/acpi2.c; - enable = ia64_efi; -}; From b764f436e78a5899c4b6912cc68768fcf68aeef3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Sep 2010 03:03:15 +0200 Subject: [PATCH 014/211] Add ia64 setjmp implementation to the list --- grub-core/lib/setjmp.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S index c39c91b9c..b04fd7439 100644 --- a/grub-core/lib/setjmp.S +++ b/grub-core/lib/setjmp.S @@ -8,6 +8,8 @@ #include "./mips/setjmp.S" #elif defined(__powerpc__) #include "./powerpc/setjmp.S" +#elif defined(__ia64__) +#include "./ia64/setjmp.S" #else -#error "Unknwon target cpu type" +#error "Unknown target cpu type" #endif From afef75b254473c065af83beb605857ca8b8a21dd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Sep 2010 03:05:36 +0200 Subject: [PATCH 015/211] Use finish boot services and switch to new command line interface in linux loader --- grub-core/loader/ia64/efi/linux.c | 95 ++++++++++++++++--------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c index 9020efd28..12c769a16 100644 --- a/grub-core/loader/ia64/efi/linux.c +++ b/grub-core/loader/ia64/efi/linux.c @@ -327,6 +327,7 @@ grub_linux_boot (void) grub_efi_uintn_t desc_size; grub_efi_uint32_t desc_version; grub_efi_memory_descriptor_t *mmap_buf; + grub_err_t err; /* FPSWA. */ query_fpswa (); @@ -349,18 +350,16 @@ grub_linux_boot (void) 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"); + err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, &map_key, + &desc_size, &desc_version); + if (err) + return err; 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)); @@ -494,8 +493,9 @@ grub_load_elf64 (grub_file_t file, void *buffer) return 0; } -void -grub_rescue_cmd_linux (int argc, char *argv[]) +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) { grub_file_t file = 0; char buffer[GRUB_ELF_SEARCH]; @@ -574,10 +574,12 @@ grub_rescue_cmd_linux (int argc, char *argv[]) boot_param_pages); grub_dl_unref (my_mod); } + return grub_errno; } -void -grub_rescue_cmd_initrd (int argc, char *argv[]) +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) { grub_file_t file = 0; @@ -617,10 +619,12 @@ grub_rescue_cmd_initrd (int argc, char *argv[]) fail: if (file) grub_file_close (file); + return grub_errno; } -void -grub_rescue_cmd_payload (int argc, char *argv[]) +static grub_err_t +grub_cmd_payload (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) { grub_file_t file = 0; grub_ssize_t size, len = 0; @@ -708,10 +712,12 @@ grub_rescue_cmd_payload (int argc, char *argv[]) grub_free (base); grub_free (cmdline); } + return grub_errno; } -void -grub_rescue_cmd_relocate (int argc, char *argv[]) +static grub_err_t +grub_cmd_relocate (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) { static const char * const vals[] = { "off", "on", "force"}; unsigned int i; @@ -719,6 +725,7 @@ grub_rescue_cmd_relocate (int argc, char *argv[]) if (argc == 0) { grub_printf ("relocate is %s\n", vals[relocate]); + return GRUB_ERR_NONE; } else if (argc == 1) { @@ -728,67 +735,63 @@ grub_rescue_cmd_relocate (int argc, char *argv[]) if (grub_strcmp (argv[0], vals[i]) == 0) { relocate = i; - return; + return GRUB_ERR_NONE; } - grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown relocate value"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown relocate value"); } else { - grub_error (GRUB_ERR_BAD_ARGUMENT, "accept 0 or 1 argument"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "accept 0 or 1 argument"); } + } -void -grub_rescue_cmd_fpswa (int argc, char *argv[] __attribute__((unused))) +static grub_err_t +grub_cmd_fpswa (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[] __attribute__((unused))) { if (argc != 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "Arguments not expected"); - return; + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Arguments not expected"); } query_fpswa (); if (fpswa == NULL) grub_printf ("No FPSWA loaded\n"); else grub_printf ("FPSWA revision: %x\n", fpswa->revision); + return GRUB_ERR_NONE; } +static grub_command_t cmd_linux, cmd_initrd, cmd_payload, cmd_relocate, cmd_fpswa; + GRUB_MOD_INIT(linux) { - grub_register_extcmd ("linux", grub_normal_linux_command, - GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, - "linux FILE [ARGS...]", - "Load Linux.", 0); + cmd_linux = grub_register_command ("linux", grub_cmd_linux, + "FILE [ARGS...]", "Load Linux."); - grub_register_extcmd ("initrd", grub_normal_initrd_command, - GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, - "initrd FILE", - "Load initrd.", 0); + cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, + "FILE", "Load initrd."); - grub_register_extcmd ("payload", grub_normal_cmd_payload, - GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, - "payload FILE [ARGS...]", - "Load an additional file.", 0); + cmd_payload = grub_register_command ("payload", grub_cmd_payload, + "FILE [ARGS...]", + "Load an additional file."); - grub_register_extcmd ("relocate", grub_normal_cmd_relocate, - GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, - "relocate [on|off|force]", - "Set relocate feature.", 0); + cmd_relocate = grub_register_command ("relocate", grub_cmd_relocate, + "[on|off|force]", + "Set relocate feature."); - grub_register_extcmd ("fpswa", grub_normal_cmd_fpswa, - GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, - "fpswa", - "Display FPSWA version.", 0); + cmd_fpswa = grub_register_command ("fpswa", grub_cmd_fpswa, + "", "Display FPSWA version."); my_mod = mod; } GRUB_MOD_FINI(linux) { - grub_unregister_command ("linux"); - grub_unregister_command ("initrd"); - grub_unregister_command ("payload"); - grub_unregister_command ("relocate"); - grub_unregister_command ("fpswa"); + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); + grub_unregister_command (cmd_payload); + grub_unregister_command (cmd_relocate); + grub_unregister_command (cmd_fpswa); } From c84a9b54ad9e957adb8414620af52a2a414419d0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Sep 2010 09:43:36 +0200 Subject: [PATCH 016/211] remove allocate_boot_pages and free_boot_pages. They are pointless now --- grub-core/loader/ia64/efi/linux.c | 32 +++++++++++++++---------------- include/grub/efi/efi.h | 7 ------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c index 12c769a16..61b261599 100644 --- a/grub-core/loader/ia64/efi/linux.c +++ b/grub-core/loader/ia64/efi/linux.c @@ -193,13 +193,13 @@ free_pages (void) { if (kernel_mem) { - grub_efi_free_boot_pages ((grub_addr_t) kernel_mem, kernel_pages); + grub_efi_free_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); + grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); initrd_mem = 0; } @@ -214,16 +214,16 @@ free_pages (void) { next_payload = (struct ia64_boot_payload *)payload->next; - grub_efi_free_boot_pages + grub_efi_free_pages (payload->start, page_align (payload->length) >> 12); - grub_efi_free_boot_pages ((grub_efi_physical_address_t)payload, 1); + grub_efi_free_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); + grub_efi_free_pages ((grub_efi_physical_address_t)boot_param, + boot_param_pages); boot_param = 0; } } @@ -347,7 +347,7 @@ grub_linux_boot (void) 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); + mmap_buf = grub_efi_allocate_pages (0, page_align (mmap_size) >> 12); if (! mmap_buf) grub_fatal ("cannot allocate memory map"); err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, &map_key, @@ -437,7 +437,7 @@ grub_load_elf64 (grub_file_t file, void *buffer) if (relocate != RELOCATE_FORCE) { - kernel_mem = grub_efi_allocate_boot_pages (low_addr, kernel_pages); + kernel_mem = grub_efi_allocate_pages (low_addr, kernel_pages); reloc_offset = 0; } /* Try to relocate. */ @@ -537,7 +537,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), 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); + boot_param = grub_efi_allocate_pages (0, boot_param_pages); if (boot_param == 0) { grub_error (GRUB_ERR_OUT_OF_MEMORY, @@ -557,8 +557,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), } cmdline[10] = '='; - boot_param->command_line = (grub_uint64_t)cmdline; - boot_param->efi_systab = (grub_uint64_t)grub_efi_system_table; + boot_param->command_line = (grub_uint64_t) cmdline; + boot_param->efi_systab = (grub_uint64_t) grub_efi_system_table; grub_errno = GRUB_ERR_NONE; @@ -570,8 +570,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (grub_errno != GRUB_ERR_NONE) { - grub_efi_free_boot_pages ((grub_efi_physical_address_t)boot_param, - boot_param_pages); + grub_efi_free_pages ((grub_efi_physical_address_t) boot_param, + boot_param_pages); grub_dl_unref (my_mod); } return grub_errno; @@ -603,7 +603,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), initrd_size = grub_file_size (file); initrd_pages = (page_align (initrd_size) >> 12); - initrd_mem = grub_efi_allocate_boot_pages (0, initrd_pages); + initrd_mem = grub_efi_allocate_pages (0, initrd_pages); if (! initrd_mem) grub_fatal ("cannot allocate pages"); @@ -650,7 +650,7 @@ grub_cmd_payload (grub_command_t cmd __attribute__ ((unused)), goto fail; size = grub_file_size (file); - base = grub_efi_allocate_boot_pages (0, page_align (size) >> 12); + base = grub_efi_allocate_pages (0, page_align (size) >> 12); if (! base) goto fail; @@ -672,7 +672,7 @@ grub_cmd_payload (grub_command_t cmd __attribute__ ((unused)), grub_error (GRUB_ERR_OUT_OF_RANGE, "payload command line too long"); goto fail; } - payload = grub_efi_allocate_boot_pages (0, 1); + payload = grub_efi_allocate_pages (0, 1); if (! payload) goto fail; diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index ea354e5ce..e9c57dd11 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -42,13 +42,6 @@ EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, 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, From 07329a9ac9a2ea530d4e904541d1587e0b2c5cf1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Sep 2010 09:44:32 +0200 Subject: [PATCH 017/211] Fix some compilation problems --- Makefile.util.def | 1 + grub-core/commands/efi/memmap.c | 27 +++++++++++++++------------ grub-core/kern/dl.c | 10 +++++++++- include/grub/dl.h | 8 ++++---- include/grub/ia64/efi/memory.h | 1 + include/grub/ia64/efi/misc.h | 4 ++++ 6 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 include/grub/ia64/efi/memory.h diff --git a/Makefile.util.def b/Makefile.util.def index 28e66a067..24adba282 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -365,6 +365,7 @@ script = { i386_efi = util/i386/efi/grub-install.in; x86_64_efi = util/i386/efi/grub-install.in; + ia64_efi = util/grub-install.in; i386_ieee1275 = util/ieee1275/grub-install.in; powerpc_ieee1275 = util/ieee1275/grub-install.in; diff --git a/grub-core/commands/efi/memmap.c b/grub-core/commands/efi/memmap.c index d49e02080..e7c140cff 100644 --- a/grub-core/commands/efi/memmap.c +++ b/grub-core/commands/efi/memmap.c @@ -22,12 +22,15 @@ #include #include #include +#include #define ADD_MEMORY_DESCRIPTOR(desc, size) \ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) static grub_err_t -grub_cmd_memmap (struct grub_arg_list *state, int argc, char **args) +grub_cmd_memmap (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) { grub_efi_uintn_t map_size; grub_efi_memory_descriptor_t *memory_map; @@ -80,22 +83,22 @@ grub_cmd_memmap (struct grub_arg_list *state, int argc, char **args) 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); + (unsigned long long) desc->physical_start, + (unsigned long long) desc->physical_start + (desc->num_pages << 12) - 1, + (unsigned long) desc->num_pages); size = desc->num_pages << (12 - 10); if (size < 1024) - grub_printf (" %4uKB", size); + grub_printf (" %4uKB", (unsigned) size); else { size /= 1024; if (size < 1024) - grub_printf (" %4uMB", size); + grub_printf (" %4uMB", (unsigned) size); else { size /= 1024; - grub_printf (" %4uGB", size); + grub_printf (" %4uGB", (unsigned) size); } } @@ -129,15 +132,15 @@ grub_cmd_memmap (struct grub_arg_list *state, int argc, char **args) return 0; } +static grub_command_t cmd; + GRUB_MOD_INIT(memmap) { - (void)mod; /* To stop warning. */ - grub_register_extcmd ("memmap", grub_cmd_memmap, GRUB_COMMAND_FLAG_BOTH, - "memmap", - "Display memory map.", NULL); + cmd = grub_register_command ("memmap", grub_cmd_memmap, + "", "Display memory map."); } GRUB_MOD_FINI(memmap) { - grub_unregister_extcmd ("memmap"); + grub_unregister_command (cmd); } diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index fe3fd0014..4d7929073 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -37,6 +37,10 @@ #define GRUB_MODULES_MACHINE_READONLY #endif +#ifdef __ia64__ +#include +#endif + grub_dl_t grub_dl_head = 0; @@ -545,6 +549,7 @@ grub_dl_load_core (void *addr, grub_size_t size) return mod; } +#ifdef __ia64__ void grub_init_module (const char *name, void (*init)(grub_dl_t), void (*fini)(void)) @@ -555,7 +560,7 @@ grub_init_module (const char *name, if (! mod) return; - mod->name = name; + mod->name = (char *) name; mod->ref_count = 1; mod->dep = 0; mod->segment = 0; @@ -567,6 +572,7 @@ grub_init_module (const char *name, /* Can't fail. */ grub_dl_add (mod); } +#endif /* Load a module from the file FILENAME. */ grub_dl_t @@ -686,6 +692,7 @@ grub_dl_unload (grub_dl_t mod) return 1; } +#ifdef __ia64__ /* Unload unneeded modules. */ void grub_dl_unload_unneeded (void) @@ -705,3 +712,4 @@ grub_dl_unload_unneeded (void) p = p->next; } } +#endif diff --git a/include/grub/dl.h b/include/grub/dl.h index 04577a003..8195e948c 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -34,9 +34,9 @@ #ifndef GRUB_MOD_INIT #define GRUB_MOD_INIT(name) \ static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ -void grub_module_##name##_init (grub_dl_t); \ +void grub_##name##_init (grub_dl_t); \ void \ -grub_module_##name##_init (grub_dl_t mod) { grub_mod_init (mod); } \ +grub_##name##_init (grub_dl_t mod) { grub_mod_init (mod); } \ static void \ grub_mod_init (grub_dl_t mod __attribute__ ((unused))) #endif @@ -44,9 +44,9 @@ grub_mod_init (grub_dl_t mod __attribute__ ((unused))) #ifndef GRUB_MOD_FINI #define GRUB_MOD_FINI(name) \ static void grub_mod_fini (void) __attribute__ ((used)); \ -void grub_module_##name##_fini (void); \ +void grub_##name##_fini (void); \ void \ -grub_module_##name##_fini (void) { grub_mod_fini (); } \ +grub_##name##_fini (void) { grub_mod_fini (); } \ static void \ grub_mod_fini (void) #endif diff --git a/include/grub/ia64/efi/memory.h b/include/grub/ia64/efi/memory.h new file mode 100644 index 000000000..c9a61bb77 --- /dev/null +++ b/include/grub/ia64/efi/memory.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/ia64/efi/misc.h b/include/grub/ia64/efi/misc.h index 2b99dda62..4f9c69e32 100644 --- a/include/grub/ia64/efi/misc.h +++ b/include/grub/ia64/efi/misc.h @@ -19,5 +19,9 @@ void EXPORT_FUNC (__ia64_trampoline) (void); void EXPORT_FUNC (grub_init_modules) (void); +void +grub_init_module (const char *name, + void (*init)(grub_dl_t), void (*fini)(void)); + extern unsigned long EXPORT_VAR (__gp); From 4bec80482ea423c27c6de7a008d15ba44f8fbbfd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Sep 2010 10:21:05 +0200 Subject: [PATCH 018/211] Remove few bad hunks --- grub-core/kern/dl.c | 2 -- grub-core/loader/ia64/efi/linux.c | 1 - include/grub/ia64/efi/loader.h | 30 ------------------------------ 3 files changed, 33 deletions(-) delete mode 100644 include/grub/ia64/efi/loader.h diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 4d7929073..4d112811f 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -692,7 +692,6 @@ grub_dl_unload (grub_dl_t mod) return 1; } -#ifdef __ia64__ /* Unload unneeded modules. */ void grub_dl_unload_unneeded (void) @@ -712,4 +711,3 @@ grub_dl_unload_unneeded (void) p = p->next; } } -#endif diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c index 61b261599..d9b4c338b 100644 --- a/grub-core/loader/ia64/efi/linux.c +++ b/grub-core/loader/ia64/efi/linux.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include diff --git a/include/grub/ia64/efi/loader.h b/include/grub/ia64/efi/loader.h deleted file mode 100644 index 5471a81b5..000000000 --- a/include/grub/ia64/efi/loader.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_LOADER_MACHINE_HEADER -#define GRUB_LOADER_MACHINE_HEADER 1 - -/* It is necessary to export these functions, because normal mode commands - reuse rescue mode commands. */ -void grub_rescue_cmd_linux (int argc, char *argv[]); -void grub_rescue_cmd_initrd (int argc, char *argv[]); -void grub_rescue_cmd_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 */ From 30b4166fdea35a49e1712efe6997de210cd17ca3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 17:23:51 +0200 Subject: [PATCH 019/211] Reimport setjmp from Tristan's branch. --- ChangeLog.ia64-emu | 6 ++ grub-core/lib/ia64/longjmp.S | 162 +++++++++++++++++++++++++++++++++ grub-core/lib/ia64/setjmp.S | 171 +++++++++++++++++++++++++++++++++++ grub-core/lib/setjmp.S | 2 + 4 files changed, 341 insertions(+) create mode 100644 ChangeLog.ia64-emu create mode 100644 grub-core/lib/ia64/longjmp.S create mode 100644 grub-core/lib/ia64/setjmp.S diff --git a/ChangeLog.ia64-emu b/ChangeLog.ia64-emu new file mode 100644 index 000000000..61a3ca6de --- /dev/null +++ b/ChangeLog.ia64-emu @@ -0,0 +1,6 @@ +2008-01-28 Tristan Gingold +2010-01-18 Robert Millan + + * grub-core/lib/ia64/setjmp.S: New file (from glibc). + * grub-core/lib/ia64/longjmp.S: New file (from glibc). + * grub-core/lib/setjmp.S [__ia64__]: include ia64/setjmp.S. diff --git a/grub-core/lib/ia64/longjmp.S b/grub-core/lib/ia64/longjmp.S new file mode 100644 index 000000000..729bdc76e --- /dev/null +++ b/grub-core/lib/ia64/longjmp.S @@ -0,0 +1,162 @@ +/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc. + Contributed by David Mosberger-Tang . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + Note that __sigsetjmp() did NOT flush the register stack. Instead, + we do it here since __longjmp() is usually much less frequently + invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp() + didn't (and wouldn't be able to) save ar.rnat either. This is a problem + because if we're not careful, we could end up loading random NaT bits. + There are two cases: + + (i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp) + ar.rnat contains the desired bits---preserve ar.rnat + across loadrs and write to ar.bspstore + + (ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp) + The desired ar.rnat is stored in + ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those + bits into ar.rnat after setting ar.bspstore. */ + + + +# define pPos p6 /* is rotate count positive? */ +# define pNeg p7 /* is rotate count negative? */ + + + /* __longjmp(__jmp_buf buf, int val) */ + + .text + .global longjmp + .proc longjmp +longjmp: + alloc r8=ar.pfs,2,1,0,0 + mov r27=ar.rsc + add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr + ;; + ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr + mov r10=ar.bsp + and r11=~0x3,r27 // clear ar.rsc.mode + ;; + flushrs // flush dirty regs to backing store (must be first in insn grp) + ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp + sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf + ;; + ld8 r25=[r2] // r25 <- jmpbuf.ar_unat + extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f + ;; + cmp.lt pNeg,pPos=r8,r0 + mov r2=in0 + ;; +(pPos) mov r16=r8 +(pNeg) add r16=64,r8 +(pPos) sub r17=64,r8 +(pNeg) sub r17=r0,r8 + ;; + mov ar.rsc=r11 // put RSE in enforced lazy mode + shr.u r8=r25,r16 + add r3=8,in0 // r3 <- &jmpbuf.r1 + shl r9=r25,r17 + ;; + or r25=r8,r9 + ;; + mov r26=ar.rnat + mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12) + ;; + ld8.fill.nta sp=[r2],16 // r12 (sp) + ld8.fill.nta gp=[r3],16 // r1 (gp) + dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp) + ;; + ld8.nta r16=[r2],16 // caller's unat + ld8.nta r17=[r3],16 // fpsr + ;; + ld8.fill.nta r4=[r2],16 // r4 + ld8.fill.nta r5=[r3],16 // r5 (gp) + cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp) + ;; + ld8.fill.nta r6=[r2],16 // r6 + ld8.fill.nta r7=[r3],16 // r7 + ;; + mov ar.unat=r16 // restore caller's unat + mov ar.fpsr=r17 // restore fpsr + ;; + ld8.nta r16=[r2],16 // b0 + ld8.nta r17=[r3],16 // b1 + ;; +(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp) + mov ar.bspstore=r23 // restore ar.bspstore + ;; + ld8.nta r18=[r2],16 // b2 + ld8.nta r19=[r3],16 // b3 + ;; + ld8.nta r20=[r2],16 // b4 + ld8.nta r21=[r3],16 // b5 + ;; + ld8.nta r11=[r2],16 // ar.pfs + ld8.nta r22=[r3],56 // ar.lc + ;; + ld8.nta r24=[r2],32 // pr + mov b0=r16 + ;; + ldf.fill.nta f2=[r2],32 + ldf.fill.nta f3=[r3],32 + mov b1=r17 + ;; + ldf.fill.nta f4=[r2],32 + ldf.fill.nta f5=[r3],32 + mov b2=r18 + ;; + ldf.fill.nta f16=[r2],32 + ldf.fill.nta f17=[r3],32 + mov b3=r19 + ;; + ldf.fill.nta f18=[r2],32 + ldf.fill.nta f19=[r3],32 + mov b4=r20 + ;; + ldf.fill.nta f20=[r2],32 + ldf.fill.nta f21=[r3],32 + mov b5=r21 + ;; + ldf.fill.nta f22=[r2],32 + ldf.fill.nta f23=[r3],32 + mov ar.lc=r22 + ;; + ldf.fill.nta f24=[r2],32 + ldf.fill.nta f25=[r3],32 + cmp.eq p8,p9=0,in1 + ;; + ldf.fill.nta f26=[r2],32 + ldf.fill.nta f27=[r3],32 + mov ar.pfs=r11 + ;; + ldf.fill.nta f28=[r2],32 + ldf.fill.nta f29=[r3],32 + ;; + ldf.fill.nta f30=[r2] + ldf.fill.nta f31=[r3] +(p8) mov r8=1 + + mov ar.rnat=r26 // restore ar.rnat + ;; + mov ar.rsc=r27 // restore ar.rsc +(p9) mov r8=in1 + + invala // virt. -> phys. regnum mapping may change + mov pr=r24,-1 + br.ret.dptk.few rp + .endp longjmp diff --git a/grub-core/lib/ia64/setjmp.S b/grub-core/lib/ia64/setjmp.S new file mode 100644 index 000000000..0851885c5 --- /dev/null +++ b/grub-core/lib/ia64/setjmp.S @@ -0,0 +1,171 @@ +/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc. + Contributed by David Mosberger-Tang . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + The layout of the jmp_buf is as follows. This is subject to change + and user-code should never depend on the particular layout of + jmp_buf! + + + offset: description: + ------- ------------ + 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS) + 0x008 r1 (gp) + 0x010 caller's unat + 0x018 fpsr + 0x020 r4 + 0x028 r5 + 0x030 r6 + 0x038 r7 + 0x040 rp (b0) + 0x048 b1 + 0x050 b2 + 0x058 b3 + 0x060 b4 + 0x068 b5 + 0x070 ar.pfs + 0x078 ar.lc + 0x080 pr + 0x088 ar.bsp ; unchangeable (see __longjmp.S) + 0x090 ar.unat + 0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat) + 0x0a0 f2 + 0x0b0 f3 + 0x0c0 f4 + 0x0d0 f5 + 0x0e0 f16 + 0x0f0 f17 + 0x100 f18 + 0x110 f19 + 0x120 f20 + 0x130 f21 + 0x130 f22 + 0x140 f23 + 0x150 f24 + 0x160 f25 + 0x170 f26 + 0x180 f27 + 0x190 f28 + 0x1a0 f29 + 0x1b0 f30 + 0x1c0 f31 */ + + + /* The following two entry points are the traditional entry points: */ + + .text + .global setjmp + .proc setjmp +setjmp: + alloc r8=ar.pfs,2,0,0,0 + mov in1=1 + br.cond.sptk.many __sigsetjmp + .endp setjmp + + /* __sigsetjmp(__jmp_buf buf, int savemask) */ + + .proc __sigsetjmp +__sigsetjmp: + //.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) + alloc loc1=ar.pfs,2,2,2,0 + mov r16=ar.unat + ;; + mov r17=ar.fpsr + mov r2=in0 + add r3=8,in0 + ;; + st8.spill.nta [r2]=sp,16 // r12 (sp) + st8.spill.nta [r3]=gp,16 // r1 (gp) + ;; + st8.nta [r2]=r16,16 // save caller's unat + st8.nta [r3]=r17,16 // save fpsr + add r8=0xa0,in0 + ;; + st8.spill.nta [r2]=r4,16 // r4 + st8.spill.nta [r3]=r5,16 // r5 + add r9=0xb0,in0 + ;; + stf.spill.nta [r8]=f2,32 + stf.spill.nta [r9]=f3,32 + mov loc0=rp + .body + ;; + stf.spill.nta [r8]=f4,32 + stf.spill.nta [r9]=f5,32 + mov r17=b1 + ;; + stf.spill.nta [r8]=f16,32 + stf.spill.nta [r9]=f17,32 + mov r18=b2 + ;; + stf.spill.nta [r8]=f18,32 + stf.spill.nta [r9]=f19,32 + mov r19=b3 + ;; + stf.spill.nta [r8]=f20,32 + stf.spill.nta [r9]=f21,32 + mov r20=b4 + ;; + stf.spill.nta [r8]=f22,32 + stf.spill.nta [r9]=f23,32 + mov r21=b5 + ;; + stf.spill.nta [r8]=f24,32 + stf.spill.nta [r9]=f25,32 + mov r22=ar.lc + ;; + stf.spill.nta [r8]=f26,32 + stf.spill.nta [r9]=f27,32 + mov r24=pr + ;; + stf.spill.nta [r8]=f28,32 + stf.spill.nta [r9]=f29,32 + ;; + stf.spill.nta [r8]=f30 + stf.spill.nta [r9]=f31 + + st8.spill.nta [r2]=r6,16 // r6 + st8.spill.nta [r3]=r7,16 // r7 + ;; + mov r23=ar.bsp + mov r25=ar.unat + mov out0=in0 + + st8.nta [r2]=loc0,16 // b0 + st8.nta [r3]=r17,16 // b1 + mov out1=in1 + ;; + st8.nta [r2]=r18,16 // b2 + st8.nta [r3]=r19,16 // b3 + ;; + st8.nta [r2]=r20,16 // b4 + st8.nta [r3]=r21,16 // b5 + ;; + st8.nta [r2]=loc1,16 // ar.pfs + st8.nta [r3]=r22,16 // ar.lc + ;; + st8.nta [r2]=r24,16 // pr + st8.nta [r3]=r23,16 // ar.bsp + ;; + st8.nta [r2]=r25 // ar.unat + st8.nta [r3]=in0 // &__jmp_buf + mov r8=0 + mov rp=loc0 + mov ar.pfs=loc1 + br.ret.sptk.many rp + + .endp __sigsetjmp diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S index c39c91b9c..7e669d4ff 100644 --- a/grub-core/lib/setjmp.S +++ b/grub-core/lib/setjmp.S @@ -8,6 +8,8 @@ #include "./mips/setjmp.S" #elif defined(__powerpc__) #include "./powerpc/setjmp.S" +#elif defined(__ia64__) +#include "./ia64/setjmp.S" #else #error "Unknwon target cpu type" #endif From 3b2bdd6f73c0e7bf082f8553503b27c3806eb224 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 8 Sep 2010 01:50:12 +0200 Subject: [PATCH 020/211] Add missing headers for ia64 --- include/grub/ia64/setjmp.h | 28 ++++++++++++++++++++++++++++ include/grub/ia64/time.h | 28 ++++++++++++++++++++++++++++ include/grub/ia64/types.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 include/grub/ia64/setjmp.h create mode 100644 include/grub/ia64/time.h create mode 100644 include/grub/ia64/types.h diff --git a/include/grub/ia64/setjmp.h b/include/grub/ia64/setjmp.h new file mode 100644 index 000000000..a71c9c56d --- /dev/null +++ b/include/grub/ia64/setjmp.h @@ -0,0 +1,28 @@ +/* Define the machine-dependent type `jmp_buf'. Linux/IA-64 version. + Copyright (C) 1999, 2000, 2008 Free Software Foundation, Inc. + Contributed by David Mosberger-Tang . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* User code must not depend on the internal representation of jmp_buf. */ + +#define _JBLEN 70 + +/* the __jmp_buf element type should be __float80 per ABI... */ +typedef long grub_jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /* guarantees 128-bit alignment! */ + +int grub_setjmp (grub_jmp_buf env); +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); diff --git a/include/grub/ia64/time.h b/include/grub/ia64/time.h new file mode 100644 index 000000000..03ee79fa4 --- /dev/null +++ b/include/grub/ia64/time.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007, 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +static __inline void +grub_cpu_idle (void) +{ + /* FIXME: not implemented */ +} + +#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/ia64/types.h b/include/grub/ia64/types.h new file mode 100644 index 000000000..91a546dd2 --- /dev/null +++ b/include/grub/ia64/types.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 8 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 8 + +/* ia64 is little-endian (usually). */ +#undef GRUB_TARGET_WORDS_BIGENDIAN + + +#endif /* ! GRUB_TYPES_CPU_HEADER */ From 22a85f6b0abc04e881b8e376cc0793992dc23e16 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 8 Sep 2010 01:51:31 +0200 Subject: [PATCH 021/211] Add ia64-specific libgcc symbols --- configure.ac | 2 +- include/grub/libgcc.h | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d362f68a5..ca886b5dc 100644 --- a/configure.ac +++ b/configure.ac @@ -542,7 +542,7 @@ CFLAGS="$CFLAGS -Wl,--defsym,abort=main" fi # Check for libgcc symbols -AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x) +AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3) if test "x$TARGET_APPLE_CC" = x1 ; then CFLAGS="$TARGET_CFLAGS -nostdlib" diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h index d0adae8c1..703182577 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -38,8 +38,30 @@ void EXPORT_FUNC (__bswapsi2) (void); # ifdef HAVE___BSWAPDI2 void EXPORT_FUNC (__bswapdi2) (void); # endif +# ifdef HAVE___UDIVSI3 +void EXPORT_FUNC (__udivsi3) (void); +# endif +# ifdef HAVE___UMODSI3 +void EXPORT_FUNC (__umodsi3) (void); +# endif +# ifdef HAVE___UMODDI3 +void EXPORT_FUNC (__umoddi3) (void); +# endif +# ifdef HAVE___UDIVDI3 +void EXPORT_FUNC (__udivdi3) (void); +# endif +# ifdef HAVE___DIVSI3 +void EXPORT_FUNC (__divsi3) (void); +# endif +# ifdef HAVE___UMODSI3 +void EXPORT_FUNC (__modsi3) (void); +# endif #endif +# ifdef HAVE___IA64_TRAMPOLINE +void EXPORT_FUNC (__ia64_trampoline) (void); +# endif + #ifdef HAVE___TRAMPOLINE_SETUP void EXPORT_FUNC (__trampoline_setup) (void); #endif From c0e103e4dacffd9d9348cc753eaf89405564df98 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 8 Nov 2010 16:51:50 +0100 Subject: [PATCH 022/211] Support for partitioned loop devices. Improved devmapper support --- grub-core/kern/emu/getroot.c | 88 +++++++++++++++++++++++++---------- grub-core/kern/emu/hostdisk.c | 71 +++++++++++++++++++++++++++- 2 files changed, 133 insertions(+), 26 deletions(-) diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 0433d49ed..a99bee9a4 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -32,6 +32,10 @@ #include #include +#ifdef HAVE_DEVICE_MAPPER +# include +#endif + #ifdef __GNU__ #include #include @@ -560,30 +564,66 @@ grub_guess_root_device (const char *dir) } static int -grub_util_is_dmraid (const char *os_dev) +grub_util_is_lvm (const char *os_dev) { - if (! strncmp (os_dev, "/dev/mapper/nvidia_", 19)) - return 1; - else if (! strncmp (os_dev, "/dev/mapper/isw_", 16)) - return 1; - else if (! strncmp (os_dev, "/dev/mapper/hpt37x_", 19)) - return 1; - else if (! strncmp (os_dev, "/dev/mapper/hpt45x_", 19)) - return 1; - else if (! strncmp (os_dev, "/dev/mapper/via_", 16)) - return 1; - else if (! strncmp (os_dev, "/dev/mapper/lsi_", 16)) - return 1; - else if (! strncmp (os_dev, "/dev/mapper/pdc_", 16)) - return 1; - else if (! strncmp (os_dev, "/dev/mapper/jmicron_", 20)) - return 1; - else if (! strncmp (os_dev, "/dev/mapper/asr_", 16)) - return 1; - else if (! strncmp (os_dev, "/dev/mapper/sil_", 16)) - return 1; + if ((strncmp ("/dev/mapper/", os_dev, 12) != 0)) + return 0; + +#ifdef HAVE_DEVICE_MAPPER + { + struct dm_tree *tree; + uint32_t maj, min; + struct dm_tree_node *node = NULL, *child; + void *handle; + const char *node_uuid, *mapper_name = NULL, *child_uuid, *child_name; + struct stat st; - return 0; + if (stat (os_dev, &st) < 0) + return 0; + + tree = dm_tree_create (); + if (! tree) + { + grub_printf ("Failed to create tree\n"); + grub_dprintf ("hostdisk", "dm_tree_create failed\n"); + return 0; + } + + maj = major (st.st_rdev); + min = minor (st.st_rdev); + + if (! dm_tree_add_dev (tree, maj, min)) + { + grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); + dm_tree_free (tree); + return 0; + } + + node = dm_tree_find_node (tree, maj, min); + if (! node) + { + grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); + dm_tree_free (tree); + return 0; + } + node_uuid = dm_tree_node_get_uuid (node); + if (! node_uuid) + { + grub_dprintf ("hostdisk", "%s has no DM uuid\n", os_dev); + dm_tree_free (tree); + return 0; + } + if (strncmp (node_uuid, "LVM-", 4) != 0) + { + dm_tree_free (tree); + return 0; + } + dm_tree_free (tree); + return 1; + } +#else + return 1; +#endif /* HAVE_DEVICE_MAPPER */ } int @@ -595,9 +635,7 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) return GRUB_DEV_ABSTRACTION_NONE; /* Check for LVM. */ - if (!strncmp (os_dev, "/dev/mapper/", 12) - && ! grub_util_is_dmraid (os_dev) - && strncmp (os_dev, "/dev/mapper/mpath", 17) != 0) + if (grub_util_is_lvm (os_dev)) return GRUB_DEV_ABSTRACTION_LVM; /* Check for RAID. */ diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 12dbe7469..2a798a3cd 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1035,6 +1035,55 @@ make_device_name (int drive, int dos_part, int bsd_part) return ret; } +#ifdef HAVE_DEVICE_MAPPER +static int +grub_util_get_dm_node_linear_info (const char *dev, + int *maj, int *min) +{ + struct dm_task *dmt; + void *next = NULL; + uint64_t length, start; + char *target, *params; + const char *node_name; + char *ptr; + int major, minor; + + dmt = dm_task_create(DM_DEVICE_TABLE); + if (!dmt) + return 0; + + if (!dm_task_set_name(dmt, dev)) + return 0; + dm_task_no_open_count(dmt); + if (!dm_task_run(dmt)) + return 0; + next = dm_get_next_target(dmt, next, &start, &length, + &target, ¶ms); + if (grub_strcmp (target, "linear") != 0) + return 0; + major = grub_strtoul (params, &ptr, 10); + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + if (*ptr != ':') + return 0; + ptr++; + minor = grub_strtoul (ptr, 0, 10); + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + if (maj) + *maj = major; + if (min) + *min = minor; + return 1; +} +#endif + static char * convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) { @@ -1211,9 +1260,29 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) node = NULL; goto devmapper_out; } - else if (strncmp (node_uuid, "DMRAID-", 7) != 0) + if (strncmp (node_uuid, "LVM-", 4) == 0) { + grub_dprintf ("hostdisk", "%s is an LVM\n", path); + node = NULL; + goto devmapper_out; + } + if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + int major, minor; + const char *node_name; grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path); + + if ((node_name = dm_tree_node_get_name (node)) + && grub_util_get_dm_node_linear_info (node_name, + &major, &minor)) + { + if (tree) + dm_tree_free (tree); + free (path); + char *ret = grub_find_device (NULL, (major << 8) | minor); + return ret; + } + node = NULL; goto devmapper_out; } From a06eb03ad020dd530f635e2936ea29270e222c47 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Nov 2010 21:27:08 +0100 Subject: [PATCH 023/211] Support long command lines as per 2.06 Linux boot protocol --- grub-core/loader/i386/linux.c | 19 ++++++++++++++----- grub-core/loader/i386/pc/linux.c | 25 +++++++++++++++++-------- include/grub/i386/linux.h | 5 ++++- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index de4bec106..bdf66c6f6 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -54,7 +54,6 @@ #endif #define GRUB_LINUX_CL_OFFSET 0x1000 -#define GRUB_LINUX_CL_END_OFFSET 0x2000 static grub_dl_t my_mod; @@ -71,6 +70,7 @@ static grub_uint32_t prot_mode_pages; static grub_uint32_t initrd_pages; static struct grub_relocator *relocator = NULL; static void *efi_mmap_buf; +static grub_size_t maximal_cmdline_size; #ifdef GRUB_MACHINE_EFI static grub_efi_uintn_t efi_mmap_size; #else @@ -185,7 +185,7 @@ allocate_pages (grub_size_t prot_size) grub_err_t err; /* Make sure that each size is aligned to a page boundary. */ - real_size = GRUB_LINUX_CL_END_OFFSET; + real_size = GRUB_LINUX_CL_OFFSET + maximal_cmdline_size; prot_size = page_align (prot_size); mmap_size = find_mmap_size (); @@ -630,6 +630,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } + if (grub_le_to_cpu16 (lh.version) >= 0x0206) + maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1; + else + maximal_cmdline_size = 256; + + if (maximal_cmdline_size < 128) + maximal_cmdline_size = 128; + setup_sects = lh.setup_sects; /* If SETUP_SECTS is not set, set it to the default (4). */ @@ -643,7 +651,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; params = (struct linux_kernel_params *) real_mode_mem; - grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET); + grub_memset (params, 0, GRUB_LINUX_CL_OFFSET + maximal_cmdline_size); grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); params->ps_mouse = params->padding10 = 0; @@ -845,8 +853,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* Copy kernel parameters. */ for (i = 1; i < argc - && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem - + GRUB_LINUX_CL_END_OFFSET); + && dest + grub_strlen (argv[i]) + 2 < ((char *) real_mode_mem + + GRUB_LINUX_CL_OFFSET + + maximal_cmdline_size); i++) { *dest++ = ' '; diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index 90de70f66..44da0ad90 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -36,7 +36,6 @@ #include #define GRUB_LINUX_CL_OFFSET 0x9000 -#define GRUB_LINUX_CL_END_OFFSET 0x90FF static grub_dl_t my_mod; @@ -46,6 +45,7 @@ static struct grub_relocator *relocator = NULL; static grub_addr_t grub_linux_real_target; static char *grub_linux_real_chunk; static grub_size_t grub_linux16_prot_size; +static grub_size_t maximal_cmdline_size; static grub_err_t grub_linux16_boot (void) @@ -126,15 +126,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), setup_sects = lh.setup_sects; linux_mem_size = 0; + maximal_cmdline_size = 256; + if (lh.header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE) && grub_le_to_cpu16 (lh.version) >= 0x0200) { grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL); lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; + if (grub_le_to_cpu16 (lh.version) >= 0x0206) + maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1; + /* Put the real mode part at as a high location as possible. */ grub_linux_real_target = grub_mmap_get_lower () - - GRUB_LINUX_SETUP_MOVE_SIZE; + - (GRUB_LINUX_CL_OFFSET + maximal_cmdline_size); /* But it must not exceed the traditional area. */ if (grub_linux_real_target > GRUB_LINUX_OLD_REAL_MODE_ADDR) grub_linux_real_target = GRUB_LINUX_OLD_REAL_MODE_ADDR; @@ -151,7 +156,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), { lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC); lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET); - lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_SETUP_MOVE_SIZE); + lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET + + maximal_cmdline_size); } } else @@ -183,12 +189,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - if (grub_linux_real_target + GRUB_LINUX_SETUP_MOVE_SIZE + if (grub_linux_real_target + GRUB_LINUX_CL_OFFSET + maximal_cmdline_size > grub_mmap_get_lower ()) { grub_error (GRUB_ERR_OUT_OF_RANGE, "too small lower memory (0x%x > 0x%x)", - grub_linux_real_target + GRUB_LINUX_SETUP_MOVE_SIZE, + grub_linux_real_target + GRUB_LINUX_CL_OFFSET + + maximal_cmdline_size, (int) grub_mmap_get_lower ()); goto fail; } @@ -261,7 +268,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_addr (relocator, &ch, grub_linux_real_target, - GRUB_LINUX_SETUP_MOVE_SIZE); + GRUB_LINUX_CL_OFFSET + + maximal_cmdline_size); if (err) return err; grub_linux_real_chunk = get_virtual_current_address (ch); @@ -294,8 +302,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* Copy kernel parameters. */ for (i = 1; i < argc - && dest + grub_strlen (argv[i]) + 1 < (grub_linux_real_chunk - + GRUB_LINUX_CL_END_OFFSET); + && dest + grub_strlen (argv[i]) + 2 < (grub_linux_real_chunk + + GRUB_LINUX_CL_OFFSET + + maximal_cmdline_size); i++) { *dest++ = ' '; diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index 63f99db62..ad59b3452 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -41,7 +41,6 @@ #define GRUB_LINUX_VID_MODE_ASK 0xFFFD #define GRUB_LINUX_VID_MODE_VESA_START 0x0300 -#define GRUB_LINUX_SETUP_MOVE_SIZE 0x9100 #define GRUB_LINUX_CL_MAGIC 0xA33F #ifdef __x86_64__ @@ -126,6 +125,10 @@ struct linux_kernel_header grub_uint16_t pad1; /* Unused */ grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */ grub_uint32_t initrd_addr_max; /* Highest address for initrd */ + grub_uint32_t kernel_alignment; + grub_uint8_t relocatable; + grub_uint8_t pad[3]; + grub_uint32_t cmdline_size; } __attribute__ ((packed)); /* Boot parameters for Linux based on 2.6.12. This is used by the setup From 332fa368872a57f945a7387cc1b931e83f197cb0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 8 Dec 2010 21:22:46 +0100 Subject: [PATCH 024/211] some squash4 code. Works only in very easy cases. --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/squash4.c | 384 ++++++++++++++++++++++++++++++++++++ 3 files changed, 390 insertions(+) create mode 100644 grub-core/fs/squash4.c diff --git a/Makefile.util.def b/Makefile.util.def index f3cd1d234..8eec8d0f7 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -65,6 +65,7 @@ library = { common = grub-core/fs/ntfscomp.c; common = grub-core/fs/reiserfs.c; common = grub-core/fs/sfs.c; + common = grub-core/fs/squash4.c; common = grub-core/fs/tar.c; common = grub-core/fs/udf.c; common = grub-core/fs/ufs2.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index c62d7d12f..583218372 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -983,6 +983,11 @@ module = { common = fs/sfs.c; }; +module = { + name = squash4; + common = fs/squash4.c; +}; + module = { name = tar; common = fs/tar.c; diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c new file mode 100644 index 000000000..889f8b94c --- /dev/null +++ b/grub-core/fs/squash4.c @@ -0,0 +1,384 @@ +/* squash4.c - SquashFS */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + object format Pointed by + superblock RAW Fixed offset (0) + data RAW ? Fixed offset (60) + inode table Chunk superblock + dir table Chunk superblock + unk3 Chunk unk1 + unk1 RAW, Chunk superblock + unk2 RAW superblock + UID/GID Chunk exttblptr + exttblptr RAW superblock + + UID/GID table is the array ot uint32_t + unk1 contains pointer to unk3 followed by some chunk. + unk2 containts one uint64_t +*/ + +struct grub_squash_super +{ + grub_uint32_t magic; +#define SQUASH_MAGIC 0x73717368 + grub_uint32_t dummy1; + grub_uint32_t creation_time; + grub_uint32_t dummy2; + grub_uint32_t dummy3[4]; + grub_uint32_t dummy4[2]; + grub_uint64_t total_size; + grub_uint64_t exttbloffset; + grub_uint32_t dummy5[2]; + grub_uint64_t inodeoffset; + grub_uint64_t diroffset; + grub_uint64_t unk1offset; + grub_uint64_t unk2offset; +}; + + +/* Chunk-based */ +struct grub_squash_inode +{ + /* Same values as direlem types. */ + grub_uint16_t type; + grub_uint16_t dummy1[3]; + grub_uint32_t mtime; + grub_uint16_t dummy2[6]; + grub_uint32_t offset; + grub_uint16_t size; + grub_uint16_t dummy3; +} __attribute__ ((packed)); + +/* Chunk-based. */ +struct grub_squash_dirent_header +{ + /* Actually the value is the number of elements - 1. */ + grub_uint16_t nelems; + grub_uint16_t dummy[5]; +}; + +struct grub_squash_dirent +{ + grub_uint16_t ino; + grub_uint16_t dummy; + grub_uint16_t type; +#define SQUASH_TYPE_DIR 1 +#define SQUASH_TYPE_REGULAR 2 + /* Actually the value is the length of name - 1. */ + grub_uint16_t namelen; + char name[0]; +}; + +#define SQUASH_CHUNK_SIZE 0x2000 +#define SQUASH_CHUNK_FLAGS 0x8000 +#define SQUASH_CHUNK_UNCOMPRESSED 0x8000 + +static grub_err_t +read_chunk (grub_disk_t disk, void *buf, grub_size_t len, + grub_uint64_t chunk_start, grub_uint64_t offset) +{ + while (len > 0) + { + grub_uint64_t csize; + grub_uint16_t d; + grub_err_t err; + while (1) + { + err = grub_disk_read (disk, chunk_start >> GRUB_DISK_SECTOR_BITS, + chunk_start & (GRUB_DISK_SECTOR_SIZE - 1), + sizeof (d), &d); + if (err) + return err; + if (offset < SQUASH_CHUNK_SIZE) + break; + offset -= SQUASH_CHUNK_SIZE; + chunk_start += 2 + (grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS); + } + + csize = SQUASH_CHUNK_SIZE - offset; + if (csize > len) + csize = len; + + if (grub_le_to_cpu16 (d) & SQUASH_CHUNK_UNCOMPRESSED) + { + grub_disk_addr_t a = chunk_start + 2 + offset; + err = grub_disk_read (disk, (a >> GRUB_DISK_SECTOR_BITS), + a & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buf); + if (err) + return err; + } + else + { + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "compression not implemented yet"); + } + len -= csize; + offset += csize; + buf = (char *) buf + csize; + } + return GRUB_ERR_NONE; +} + +struct grub_squash_data +{ + grub_disk_t disk; + struct grub_squash_super sb; + struct grub_squash_inode ino; +}; + +struct grub_fshelp_node +{ + struct grub_squash_data *data; + struct grub_squash_inode ino; +}; + +static struct grub_squash_data * +squash_mount (grub_disk_t disk) +{ + struct grub_squash_super sb; + grub_err_t err; + struct grub_squash_data *data; + + err = grub_disk_read (disk, 0, 0, sizeof (sb), &sb); + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a squash4"); + if (err) + return NULL; + if (grub_le_to_cpu32 (sb.magic) != SQUASH_MAGIC) + { + grub_error (GRUB_ERR_BAD_FS, "not squash4"); + return NULL; + } + data = grub_malloc (sizeof (*data)); + if (!data) + return NULL; + data->sb = sb; + data->disk = disk; + + return data; +} + +static int +grub_squash_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + grub_uint32_t off = grub_le_to_cpu32 (dir->ino.offset) >> 16; + /* FIXME: determine this. */ + unsigned numheaders = 1; + unsigned i, j; + for (j = 0; j < numheaders; j++) + { + struct grub_squash_dirent_header dh; + grub_err_t err; + + err = read_chunk (dir->data->disk, &dh, sizeof (dh), + grub_le_to_cpu64 (dir->data->sb.diroffset), off); + if (err) + return 0; + off += sizeof (dh); + for (i = 0; i < (unsigned) grub_le_to_cpu16 (dh.nelems) + 1; i++) + { + char *buf; + int r; + struct grub_fshelp_node *node; + enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG; + struct grub_squash_dirent di; + struct grub_squash_inode ino; + + err = read_chunk (dir->data->disk, &di, sizeof (di), + grub_le_to_cpu64 (dir->data->sb.diroffset), off); + if (err) + return 0; + off += sizeof (di); + + err = read_chunk (dir->data->disk, &ino, sizeof (ino), + grub_le_to_cpu64 (dir->data->sb.inodeoffset), + grub_le_to_cpu16 (di.ino)); + if (err) + return 0; + + buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2); + if (!buf) + return 0; + err = read_chunk (dir->data->disk, buf, + grub_le_to_cpu16 (di.namelen) + 1, + grub_le_to_cpu64 (dir->data->sb.diroffset), off); + if (err) + return 0; + + off += grub_le_to_cpu16 (di.namelen) + 1; + buf[grub_le_to_cpu16 (di.namelen) + 1] = 0; + if (grub_le_to_cpu16 (ino.type) == SQUASH_TYPE_DIR) + filetype = GRUB_FSHELP_DIR; + node = grub_malloc (sizeof (*node)); + if (! node) + return 0; + *node = *dir; + node->ino = ino; + r = hook (buf, filetype, node); + + grub_free (buf); + if (r) + return r; + } + } + return 0; +} + +static grub_err_t +make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) +{ + /* FIXME */ + grub_memset (root, 0, sizeof (*root)); + root->data = data; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_squash_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)) +{ + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node __attribute__ ((unused))) + { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + return hook (filename, &info); + } + + struct grub_squash_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + struct grub_fshelp_node root; + grub_err_t err; + + data = squash_mount (device->disk); + if (! data) + return grub_errno; + + err = make_root_node (data, &root); + if (err) + return err; + + grub_fshelp_find_file (path, &root, &fdiro, grub_squash_iterate_dir, + NULL, GRUB_FSHELP_DIR); + if (!grub_errno) + grub_squash_iterate_dir (fdiro, iterate); + + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_squash_open (struct grub_file *file, const char *name) +{ + struct grub_squash_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + struct grub_fshelp_node root; + grub_err_t err; + + data = squash_mount (file->device->disk); + if (! data) + return grub_errno; + + err = make_root_node (data, &root); + if (err) + return err; + + grub_fshelp_find_file (name, &root, &fdiro, grub_squash_iterate_dir, + NULL, GRUB_FSHELP_REG); + if (grub_errno) + { + grub_free (data); + return grub_errno; + } + file->data = data; + data->ino = fdiro->ino; + file->size = grub_le_to_cpu16 (fdiro->ino.size); + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_squash_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_err_t err; + grub_uint64_t a; + struct grub_squash_data *data = file->data; + + a = sizeof (struct grub_squash_super) + grub_le_to_cpu32 (data->ino.offset); + + err = grub_disk_read (file->device->disk, a >> GRUB_DISK_SECTOR_BITS, + a & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); + if (err) + return -1; + return len; +} + +static grub_err_t +grub_squash_close (grub_file_t file) +{ + grub_free (file->data); + return GRUB_ERR_NONE; +} + +static struct grub_fs grub_squash_fs = + { + .name = "squash4", + .dir = grub_squash_dir, + .open = grub_squash_open, + .read = grub_squash_read, + .close = grub_squash_close, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif + .next = 0 + }; + +GRUB_MOD_INIT(squash4) +{ + grub_fs_register (&grub_squash_fs); +} + +GRUB_MOD_FINI(squash4) +{ + grub_fs_unregister (&grub_squash_fs); +} + From 1deadc83f55187f1ba889d6533341850cb3a5f50 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 8 Dec 2010 23:03:59 +0100 Subject: [PATCH 025/211] extend size to 32-bit and handle file->offset --- grub-core/fs/squash4.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 889f8b94c..f3ac1f474 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -72,8 +72,7 @@ struct grub_squash_inode grub_uint32_t mtime; grub_uint16_t dummy2[6]; grub_uint32_t offset; - grub_uint16_t size; - grub_uint16_t dummy3; + grub_uint32_t size; } __attribute__ ((packed)); /* Chunk-based. */ @@ -330,9 +329,10 @@ grub_squash_open (struct grub_file *file, const char *name) grub_free (data); return grub_errno; } + file->data = data; data->ino = fdiro->ino; - file->size = grub_le_to_cpu16 (fdiro->ino.size); + file->size = grub_le_to_cpu32 (fdiro->ino.size); return GRUB_ERR_NONE; } @@ -343,7 +343,8 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) grub_uint64_t a; struct grub_squash_data *data = file->data; - a = sizeof (struct grub_squash_super) + grub_le_to_cpu32 (data->ino.offset); + a = sizeof (struct grub_squash_super) + grub_le_to_cpu32 (data->ino.offset) + + file->offset; err = grub_disk_read (file->device->disk, a >> GRUB_DISK_SECTOR_BITS, a & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); From 0a040470e53c4620d93249d5aba40097c93740d8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 00:04:36 +0100 Subject: [PATCH 026/211] determine root inode on squash4fs --- grub-core/fs/squash4.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index f3ac1f474..bd50265a8 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -52,7 +52,8 @@ struct grub_squash_super grub_uint32_t creation_time; grub_uint32_t dummy2; grub_uint32_t dummy3[4]; - grub_uint32_t dummy4[2]; + grub_uint32_t root_ino; + grub_uint32_t dummy4; grub_uint64_t total_size; grub_uint64_t exttbloffset; grub_uint32_t dummy5[2]; @@ -258,10 +259,12 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, static grub_err_t make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) { - /* FIXME */ grub_memset (root, 0, sizeof (*root)); root->data = data; - return GRUB_ERR_NONE; + + return read_chunk (data->disk, &root->ino, sizeof (root->ino), + grub_le_to_cpu64 (data->sb.inodeoffset), + grub_le_to_cpu32 (data->sb.root_ino)); } static grub_err_t From 7ed6c3e85f51a59d0758de6363d7acd9804c2e21 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 02:48:59 +0100 Subject: [PATCH 027/211] Honor chunk number for directories --- grub-core/fs/squash4.c | 48 ++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index bd50265a8..1622d3736 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -52,7 +52,8 @@ struct grub_squash_super grub_uint32_t creation_time; grub_uint32_t dummy2; grub_uint32_t dummy3[4]; - grub_uint32_t root_ino; + grub_uint16_t root_ino_offset; + grub_uint16_t root_ino_chunk; grub_uint32_t dummy4; grub_uint64_t total_size; grub_uint64_t exttbloffset; @@ -71,11 +72,19 @@ struct grub_squash_inode grub_uint16_t type; grub_uint16_t dummy1[3]; grub_uint32_t mtime; - grub_uint16_t dummy2[6]; + grub_uint16_t dummy2[2]; + grub_uint16_t chunk; + grub_uint16_t dummy3[3]; grub_uint32_t offset; grub_uint32_t size; } __attribute__ ((packed)); +static inline unsigned +decode_chunk_number (grub_uint16_t in) +{ + return (grub_le_to_cpu16 (in) & 0xff) / 2; +} + /* Chunk-based. */ struct grub_squash_dirent_header { @@ -102,8 +111,10 @@ struct grub_squash_dirent static grub_err_t read_chunk (grub_disk_t disk, void *buf, grub_size_t len, - grub_uint64_t chunk_start, grub_uint64_t offset) + grub_uint64_t chunk, unsigned nchunk, grub_off_t offset) { + grub_uint64_t chunk_start; + chunk_start = grub_le_to_cpu64 (chunk); while (len > 0) { grub_uint64_t csize; @@ -116,9 +127,12 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len, sizeof (d), &d); if (err) return err; - if (offset < SQUASH_CHUNK_SIZE) + if (!nchunk && offset < SQUASH_CHUNK_SIZE) break; - offset -= SQUASH_CHUNK_SIZE; + if (nchunk) + nchunk--; + else + offset -= SQUASH_CHUNK_SIZE; chunk_start += 2 + (grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS); } @@ -197,13 +211,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, /* FIXME: determine this. */ unsigned numheaders = 1; unsigned i, j; + for (j = 0; j < numheaders; j++) { struct grub_squash_dirent_header dh; grub_err_t err; err = read_chunk (dir->data->disk, &dh, sizeof (dh), - grub_le_to_cpu64 (dir->data->sb.diroffset), off); + dir->data->sb.diroffset, + decode_chunk_number (dir->ino.chunk), off); if (err) return 0; off += sizeof (dh); @@ -217,14 +233,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, struct grub_squash_inode ino; err = read_chunk (dir->data->disk, &di, sizeof (di), - grub_le_to_cpu64 (dir->data->sb.diroffset), off); + dir->data->sb.diroffset, + decode_chunk_number (dir->ino.chunk), off); if (err) return 0; off += sizeof (di); err = read_chunk (dir->data->disk, &ino, sizeof (ino), - grub_le_to_cpu64 (dir->data->sb.inodeoffset), - grub_le_to_cpu16 (di.ino)); + dir->data->sb.inodeoffset, + 0, + grub_cpu_to_le16 (di.ino)); if (err) return 0; @@ -233,7 +251,8 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, return 0; err = read_chunk (dir->data->disk, buf, grub_le_to_cpu16 (di.namelen) + 1, - grub_le_to_cpu64 (dir->data->sb.diroffset), off); + dir->data->sb.diroffset, + decode_chunk_number (dir->ino.chunk), off); if (err) return 0; @@ -261,10 +280,11 @@ make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) { grub_memset (root, 0, sizeof (*root)); root->data = data; - - return read_chunk (data->disk, &root->ino, sizeof (root->ino), - grub_le_to_cpu64 (data->sb.inodeoffset), - grub_le_to_cpu32 (data->sb.root_ino)); + + return read_chunk (data->disk, &root->ino, sizeof (root->ino), + data->sb.inodeoffset, + decode_chunk_number (data->sb.root_ino_chunk), + grub_cpu_to_le16 (data->sb.root_ino_offset)); } static grub_err_t From 948ebd7e91f29efea22bc4987582efb827940294 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 17:06:49 +0100 Subject: [PATCH 028/211] Support fragments and chunks for data --- grub-core/fs/squash4.c | 91 +++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 1622d3736..6fc2bc11b 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -28,16 +28,16 @@ #include /* - object format Pointed by - superblock RAW Fixed offset (0) - data RAW ? Fixed offset (60) - inode table Chunk superblock - dir table Chunk superblock - unk3 Chunk unk1 - unk1 RAW, Chunk superblock - unk2 RAW superblock - UID/GID Chunk exttblptr - exttblptr RAW superblock + object format Pointed by + superblock RAW Fixed offset (0) + data RAW ? Fixed offset (60) + inode table Chunk superblock + dir table Chunk superblock + fragment table Chunk unk1 + unk1 RAW, Chunk superblock + unk2 RAW superblock + UID/GID Chunk exttblptr + exttblptr RAW superblock UID/GID table is the array ot uint32_t unk1 contains pointer to unk3 followed by some chunk. @@ -73,8 +73,8 @@ struct grub_squash_inode grub_uint16_t dummy1[3]; grub_uint32_t mtime; grub_uint16_t dummy2[2]; - grub_uint16_t chunk; - grub_uint16_t dummy3[3]; + grub_uint32_t chunk; + grub_uint32_t fragment; grub_uint32_t offset; grub_uint32_t size; } __attribute__ ((packed)); @@ -105,10 +105,30 @@ struct grub_squash_dirent char name[0]; }; +struct grub_squash_frag_desc +{ + grub_uint64_t offset; + grub_uint64_t dummy; +}; + #define SQUASH_CHUNK_SIZE 0x2000 #define SQUASH_CHUNK_FLAGS 0x8000 #define SQUASH_CHUNK_UNCOMPRESSED 0x8000 +struct grub_squash_data +{ + grub_disk_t disk; + struct grub_squash_super sb; + struct grub_squash_inode ino; + grub_uint64_t fragments; +}; + +struct grub_fshelp_node +{ + struct grub_squash_data *data; + struct grub_squash_inode ino; +}; + static grub_err_t read_chunk (grub_disk_t disk, void *buf, grub_size_t len, grub_uint64_t chunk, unsigned nchunk, grub_off_t offset) @@ -161,25 +181,13 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len, return GRUB_ERR_NONE; } -struct grub_squash_data -{ - grub_disk_t disk; - struct grub_squash_super sb; - struct grub_squash_inode ino; -}; - -struct grub_fshelp_node -{ - struct grub_squash_data *data; - struct grub_squash_inode ino; -}; - static struct grub_squash_data * squash_mount (grub_disk_t disk) { struct grub_squash_super sb; grub_err_t err; struct grub_squash_data *data; + grub_uint64_t frag; err = grub_disk_read (disk, 0, 0, sizeof (sb), &sb); if (grub_errno == GRUB_ERR_OUT_OF_RANGE) @@ -191,11 +199,22 @@ squash_mount (grub_disk_t disk) grub_error (GRUB_ERR_BAD_FS, "not squash4"); return NULL; } + + err = grub_disk_read (disk, grub_le_to_cpu32 (sb.unk1offset) + >> GRUB_DISK_SECTOR_BITS, + grub_le_to_cpu32 (sb.unk1offset) + & (GRUB_DISK_SECTOR_SIZE - 1), sizeof (frag), &frag); + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a squash4"); + if (err) + return NULL; + data = grub_malloc (sizeof (*data)); if (!data) return NULL; data->sb = sb; data->disk = disk; + data->fragments = frag; return data; } @@ -356,6 +375,7 @@ grub_squash_open (struct grub_file *file, const char *name) file->data = data; data->ino = fdiro->ino; file->size = grub_le_to_cpu32 (fdiro->ino.size); + return GRUB_ERR_NONE; } @@ -366,8 +386,25 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) grub_uint64_t a; struct grub_squash_data *data = file->data; - a = sizeof (struct grub_squash_super) + grub_le_to_cpu32 (data->ino.offset) - + file->offset; + a = grub_le_to_cpu32 (data->ino.offset) + file->offset; + if (grub_le_to_cpu16 (data->ino.fragment) == 0xffff) + { + if (grub_le_to_cpu32 (data->ino.chunk)) + a += grub_le_to_cpu32 (data->ino.chunk); + else + a += sizeof (struct grub_squash_super); + } + else + { + struct grub_squash_frag_desc frag; + err = read_chunk (file->device->disk, &frag, sizeof (frag), + data->fragments, 0, sizeof (frag) + * grub_le_to_cpu16 (data->ino.fragment)); + if (err) + return -1; + a += grub_le_to_cpu64 (frag.offset); + a += grub_le_to_cpu32 (data->ino.chunk); + } err = grub_disk_read (file->device->disk, a >> GRUB_DISK_SECTOR_BITS, a & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); From 99f0735fb8f961f4281eae3c76366f2eb8afdad2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 18:22:38 +0100 Subject: [PATCH 029/211] Support multi-header directories --- grub-core/fs/squash4.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 6fc2bc11b..5bb128f58 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -227,11 +227,13 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, grub_fshelp_node_t node)) { grub_uint32_t off = grub_le_to_cpu32 (dir->ino.offset) >> 16; - /* FIXME: determine this. */ - unsigned numheaders = 1; - unsigned i, j; + grub_uint32_t endoff; + unsigned i; - for (j = 0; j < numheaders; j++) + /* FIXME: why - 3 ? */ + endoff = (grub_le_to_cpu32 (dir->ino.offset) & 0xffff) + off - 3; + + while (off < endoff) { struct grub_squash_dirent_header dh; grub_err_t err; From 76e39dc8711ce85d43fa06a0a4ee9e0683091d45 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 19:23:35 +0100 Subject: [PATCH 030/211] Compressed metadata support --- grub-core/fs/squash4.c | 74 +++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 5bb128f58..8eca185f3 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -79,23 +79,19 @@ struct grub_squash_inode grub_uint32_t size; } __attribute__ ((packed)); -static inline unsigned -decode_chunk_number (grub_uint16_t in) -{ - return (grub_le_to_cpu16 (in) & 0xff) / 2; -} - /* Chunk-based. */ struct grub_squash_dirent_header { /* Actually the value is the number of elements - 1. */ grub_uint16_t nelems; - grub_uint16_t dummy[5]; + grub_uint16_t dummy1; + grub_uint32_t ino_chunk; + grub_uint16_t dummy2[2]; }; struct grub_squash_dirent { - grub_uint16_t ino; + grub_uint16_t ino_offset; grub_uint16_t dummy; grub_uint16_t type; #define SQUASH_TYPE_DIR 1 @@ -131,7 +127,7 @@ struct grub_fshelp_node static grub_err_t read_chunk (grub_disk_t disk, void *buf, grub_size_t len, - grub_uint64_t chunk, unsigned nchunk, grub_off_t offset) + grub_uint64_t chunk, grub_off_t offset) { grub_uint64_t chunk_start; chunk_start = grub_le_to_cpu64 (chunk); @@ -147,12 +143,9 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len, sizeof (d), &d); if (err) return err; - if (!nchunk && offset < SQUASH_CHUNK_SIZE) + if (offset < SQUASH_CHUNK_SIZE) break; - if (nchunk) - nchunk--; - else - offset -= SQUASH_CHUNK_SIZE; + offset -= SQUASH_CHUNK_SIZE; chunk_start += 2 + (grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS); } @@ -171,8 +164,29 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len, } else { - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "compression not implemented yet"); + char *tmp; + grub_size_t bsize = grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS; + grub_disk_addr_t a = chunk_start + 2; + tmp = grub_malloc (bsize); + if (!tmp) + return grub_errno; + /* FIXME: buffer uncompressed data. */ + err = grub_disk_read (disk, (a >> GRUB_DISK_SECTOR_BITS), + a & (GRUB_DISK_SECTOR_SIZE - 1), + bsize, tmp); + if (err) + { + grub_free (tmp); + return err; + } + + if (grub_zlib_decompress (tmp, bsize, offset, + buf, csize) < 0) + { + grub_free (tmp); + return grub_errno; + } + grub_free (tmp); } len -= csize; offset += csize; @@ -239,8 +253,8 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, grub_err_t err; err = read_chunk (dir->data->disk, &dh, sizeof (dh), - dir->data->sb.diroffset, - decode_chunk_number (dir->ino.chunk), off); + grub_le_to_cpu64 (dir->data->sb.diroffset) + + grub_le_to_cpu32 (dir->ino.chunk), off); if (err) return 0; off += sizeof (dh); @@ -254,16 +268,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, struct grub_squash_inode ino; err = read_chunk (dir->data->disk, &di, sizeof (di), - dir->data->sb.diroffset, - decode_chunk_number (dir->ino.chunk), off); + grub_le_to_cpu64 (dir->data->sb.diroffset) + + grub_le_to_cpu32 (dir->ino.chunk), off); if (err) return 0; off += sizeof (di); err = read_chunk (dir->data->disk, &ino, sizeof (ino), - dir->data->sb.inodeoffset, - 0, - grub_cpu_to_le16 (di.ino)); + grub_le_to_cpu64 (dir->data->sb.inodeoffset) + + grub_le_to_cpu32 (dh.ino_chunk), + grub_cpu_to_le16 (di.ino_offset)); if (err) return 0; @@ -272,14 +286,14 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, return 0; err = read_chunk (dir->data->disk, buf, grub_le_to_cpu16 (di.namelen) + 1, - dir->data->sb.diroffset, - decode_chunk_number (dir->ino.chunk), off); + grub_le_to_cpu64 (dir->data->sb.diroffset) + + grub_le_to_cpu32 (dir->ino.chunk), off); if (err) return 0; off += grub_le_to_cpu16 (di.namelen) + 1; buf[grub_le_to_cpu16 (di.namelen) + 1] = 0; - if (grub_le_to_cpu16 (ino.type) == SQUASH_TYPE_DIR) + if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_DIR) filetype = GRUB_FSHELP_DIR; node = grub_malloc (sizeof (*node)); if (! node) @@ -303,9 +317,9 @@ make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) root->data = data; return read_chunk (data->disk, &root->ino, sizeof (root->ino), - data->sb.inodeoffset, - decode_chunk_number (data->sb.root_ino_chunk), - grub_cpu_to_le16 (data->sb.root_ino_offset)); + grub_le_to_cpu64 (data->sb.inodeoffset) + + grub_le_to_cpu16 (data->sb.root_ino_chunk), + grub_cpu_to_le16 (data->sb.root_ino_offset)); } static grub_err_t @@ -400,7 +414,7 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_squash_frag_desc frag; err = read_chunk (file->device->disk, &frag, sizeof (frag), - data->fragments, 0, sizeof (frag) + data->fragments, sizeof (frag) * grub_le_to_cpu16 (data->ino.fragment)); if (err) return -1; From e4eaf625553ddf07f6cade56651fda7038542ea2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 19:40:11 +0100 Subject: [PATCH 031/211] Small restructuring of squash_read --- grub-core/fs/squash4.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 8eca185f3..1a121c2cf 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -402,13 +402,12 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) grub_uint64_t a; struct grub_squash_data *data = file->data; - a = grub_le_to_cpu32 (data->ino.offset) + file->offset; if (grub_le_to_cpu16 (data->ino.fragment) == 0xffff) { if (grub_le_to_cpu32 (data->ino.chunk)) - a += grub_le_to_cpu32 (data->ino.chunk); + a = grub_le_to_cpu32 (data->ino.chunk); else - a += sizeof (struct grub_squash_super); + a = sizeof (struct grub_squash_super); } else { @@ -418,10 +417,11 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) * grub_le_to_cpu16 (data->ino.fragment)); if (err) return -1; - a += grub_le_to_cpu64 (frag.offset); - a += grub_le_to_cpu32 (data->ino.chunk); + a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (data->ino.chunk); } + a += grub_le_to_cpu32 (data->ino.offset) + file->offset; + err = grub_disk_read (file->device->disk, a >> GRUB_DISK_SECTOR_BITS, a & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); if (err) From 8eef1f8244a91a1beb18bc7a94fad7347382e65e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 20:41:41 +0100 Subject: [PATCH 032/211] Compressed fragments and compressed data support --- grub-core/fs/squash4.c | 26 +++++++++++++++------ grub-core/io/gzio.c | 53 +++++++++++++++++++++++++++++++++++++++--- include/grub/deflate.h | 4 ++++ 3 files changed, 73 insertions(+), 10 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 1a121c2cf..50e5c3090 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -51,13 +51,18 @@ struct grub_squash_super grub_uint32_t dummy1; grub_uint32_t creation_time; grub_uint32_t dummy2; - grub_uint32_t dummy3[4]; + grub_uint32_t dummy3[2]; + grub_uint8_t flags; +#define SQUASH_FLAG_UNCOMPRESSED_INODES 1 +#define SQUASH_FLAG_UNCOMPRESSED_DATA 2 +#define SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS 8 + grub_uint8_t dummy4[7]; grub_uint16_t root_ino_offset; grub_uint16_t root_ino_chunk; - grub_uint32_t dummy4; + grub_uint32_t dummy5; grub_uint64_t total_size; grub_uint64_t exttbloffset; - grub_uint32_t dummy5[2]; + grub_uint32_t dummy6[2]; grub_uint64_t inodeoffset; grub_uint64_t diroffset; grub_uint64_t unk1offset; @@ -399,8 +404,9 @@ static grub_ssize_t grub_squash_read (grub_file_t file, char *buf, grub_size_t len) { grub_err_t err; - grub_uint64_t a; + grub_uint64_t a, b; struct grub_squash_data *data = file->data; + int compressed = 0; if (grub_le_to_cpu16 (data->ino.fragment) == 0xffff) { @@ -408,6 +414,7 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) a = grub_le_to_cpu32 (data->ino.chunk); else a = sizeof (struct grub_squash_super); + compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_DATA); } else { @@ -418,12 +425,17 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) if (err) return -1; a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (data->ino.chunk); + compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS); } - a += grub_le_to_cpu32 (data->ino.offset) + file->offset; + b = grub_le_to_cpu32 (data->ino.offset) + file->offset; - err = grub_disk_read (file->device->disk, a >> GRUB_DISK_SECTOR_BITS, - a & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); + /* FIXME: cache uncompressed chunks. */ + if (compressed) + err = grub_zlib_disk_read (file->device->disk, a, b, buf, len); + else + err = grub_disk_read (file->device->disk, (a + b) >> GRUB_DISK_SECTOR_BITS, + (a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); if (err) return -1; return len; diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index 248a1750e..61227b4fc 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -41,6 +41,7 @@ #include #include #include +#include #include /* @@ -62,6 +63,9 @@ struct grub_gzio /* If input is in memory following fields are used instead of file. */ grub_size_t mem_input_size, mem_input_off; grub_uint8_t *mem_input; + grub_disk_addr_t disk_input_off; + grub_disk_addr_t disk_input_start; + grub_disk_t disk_input; /* The offset at which the data starts in the underlying file. */ grub_off_t data_offset; /* The type of current block. */ @@ -383,8 +387,21 @@ get_byte (grub_gzio_t gzio) return 0; } - if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset - || gzio->inbuf_d == INBUFSIZ) + if (gzio->disk_input && (gzio->disk_input_off == gzio->data_offset + || gzio->inbuf_d == INBUFSIZ)) + { + grub_disk_addr_t d = gzio->disk_input_start + gzio->disk_input_off; + gzio->inbuf_d = 0; + grub_disk_read (gzio->disk_input, + d >> GRUB_DISK_SECTOR_BITS, + d & (GRUB_DISK_SECTOR_SIZE - 1), + INBUFSIZ, gzio->inbuf); + gzio->disk_input_off += INBUFSIZ; + } + + if (gzio->file && (grub_file_tell (gzio->file) + == (grub_off_t) gzio->data_offset + || gzio->inbuf_d == INBUFSIZ)) { gzio->inbuf_d = 0; grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ); @@ -402,8 +419,10 @@ gzio_seek (grub_gzio_t gzio, grub_off_t off) grub_error (GRUB_ERR_OUT_OF_RANGE, "attempt to seek outside of the file"); else - gzio->mem_input_off = gzio->data_offset; + gzio->mem_input_off = off; } + else if (gzio->disk_input) + gzio->disk_input_off = off; else grub_file_seek (gzio->file, off); } @@ -1297,6 +1316,34 @@ grub_zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off, return ret; } +grub_err_t +grub_zlib_disk_read (grub_disk_t disk, grub_disk_addr_t zlibstart, + grub_off_t off, char *outbuf, grub_size_t outsize) +{ + grub_gzio_t gzio = 0; + grub_ssize_t ret; + + gzio = grub_zalloc (sizeof (*gzio)); + if (! gzio) + return -1; + + gzio->disk_input_off = 0; + gzio->disk_input_start = zlibstart; + gzio->disk_input = disk; + + if (!test_zlib_header (gzio)) + { + grub_free (gzio); + return -1; + } + + ret = grub_gzio_read_real (gzio, off, outbuf, outsize); + grub_free (gzio); + + /* FIXME: Check Adler. */ + return ret < 0 ? grub_errno : GRUB_ERR_NONE; +} + static struct grub_fs grub_gzio_fs = diff --git a/include/grub/deflate.h b/include/grub/deflate.h index 6ec4eaa99..ae4a1f244 100644 --- a/include/grub/deflate.h +++ b/include/grub/deflate.h @@ -23,4 +23,8 @@ grub_ssize_t grub_zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off, char *outbuf, grub_size_t outsize); +grub_err_t +grub_zlib_disk_read (grub_disk_t disk, grub_disk_addr_t zlibstart, + grub_off_t off, char *outbuf, grub_size_t outsize); + #endif From 1fc7203971e91efde3645b97fac776872ecf7e5a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 20:48:03 +0100 Subject: [PATCH 033/211] Split grub_squash_read_data --- grub-core/fs/squash4.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 50e5c3090..2fa429803 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -401,17 +401,18 @@ grub_squash_open (struct grub_file *file, const char *name) } static grub_ssize_t -grub_squash_read (grub_file_t file, char *buf, grub_size_t len) +grub_squash_read_data (struct grub_squash_data *data, + grub_disk_t disk, const struct grub_squash_inode *ino, + grub_off_t off, char *buf, grub_size_t len) { grub_err_t err; grub_uint64_t a, b; - struct grub_squash_data *data = file->data; int compressed = 0; - if (grub_le_to_cpu16 (data->ino.fragment) == 0xffff) + if (grub_le_to_cpu16 (ino->fragment) == 0xffff) { - if (grub_le_to_cpu32 (data->ino.chunk)) - a = grub_le_to_cpu32 (data->ino.chunk); + if (grub_le_to_cpu32 (ino->chunk)) + a = grub_le_to_cpu32 (ino->chunk); else a = sizeof (struct grub_squash_super); compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_DATA); @@ -419,28 +420,37 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) else { struct grub_squash_frag_desc frag; - err = read_chunk (file->device->disk, &frag, sizeof (frag), + err = read_chunk (disk, &frag, sizeof (frag), data->fragments, sizeof (frag) - * grub_le_to_cpu16 (data->ino.fragment)); + * grub_le_to_cpu16 (ino->fragment)); if (err) return -1; - a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (data->ino.chunk); + a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (ino->chunk); compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS); } - b = grub_le_to_cpu32 (data->ino.offset) + file->offset; + b = grub_le_to_cpu32 (data->ino.offset) + off; /* FIXME: cache uncompressed chunks. */ if (compressed) - err = grub_zlib_disk_read (file->device->disk, a, b, buf, len); + err = grub_zlib_disk_read (disk, a, b, buf, len); else - err = grub_disk_read (file->device->disk, (a + b) >> GRUB_DISK_SECTOR_BITS, + err = grub_disk_read (disk, (a + b) >> GRUB_DISK_SECTOR_BITS, (a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); if (err) return -1; return len; } +static grub_ssize_t +grub_squash_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_squash_data *data = file->data; + + return grub_squash_read_data (data, file->device->disk, &data->ino, + file->offset, buf, len); +} + static grub_err_t grub_squash_close (grub_file_t file) { From 627a62fc70e75578ebcfbef71428afd1700f7e7d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 21:14:42 +0100 Subject: [PATCH 034/211] Make type-dependent portion of inode an union --- grub-core/fs/squash4.c | 49 ++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 2fa429803..409d91e47 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -75,13 +75,26 @@ struct grub_squash_inode { /* Same values as direlem types. */ grub_uint16_t type; - grub_uint16_t dummy1[3]; + grub_uint16_t dummy[3]; grub_uint32_t mtime; - grub_uint16_t dummy2[2]; - grub_uint32_t chunk; - grub_uint32_t fragment; - grub_uint32_t offset; - grub_uint32_t size; + union + { + struct { + grub_uint16_t dummy[2]; + grub_uint32_t chunk; + grub_uint32_t fragment; + grub_uint32_t offset; + grub_uint32_t size; + } file; + struct { + grub_uint16_t dummy1[2]; + grub_uint32_t chunk; + grub_uint16_t dummy2[2]; + grub_uint16_t size; + grub_uint16_t offset; + grub_uint16_t dummy3[2]; + } dir; + }; } __attribute__ ((packed)); /* Chunk-based. */ @@ -245,12 +258,12 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node)) { - grub_uint32_t off = grub_le_to_cpu32 (dir->ino.offset) >> 16; + grub_uint32_t off = grub_le_to_cpu16 (dir->ino.dir.offset); grub_uint32_t endoff; unsigned i; /* FIXME: why - 3 ? */ - endoff = (grub_le_to_cpu32 (dir->ino.offset) & 0xffff) + off - 3; + endoff = grub_le_to_cpu32 (dir->ino.dir.size) + off - 3; while (off < endoff) { @@ -259,7 +272,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, err = read_chunk (dir->data->disk, &dh, sizeof (dh), grub_le_to_cpu64 (dir->data->sb.diroffset) - + grub_le_to_cpu32 (dir->ino.chunk), off); + + grub_le_to_cpu32 (dir->ino.dir.chunk), off); if (err) return 0; off += sizeof (dh); @@ -274,7 +287,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, err = read_chunk (dir->data->disk, &di, sizeof (di), grub_le_to_cpu64 (dir->data->sb.diroffset) - + grub_le_to_cpu32 (dir->ino.chunk), off); + + grub_le_to_cpu32 (dir->ino.dir.chunk), off); if (err) return 0; off += sizeof (di); @@ -292,7 +305,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, err = read_chunk (dir->data->disk, buf, grub_le_to_cpu16 (di.namelen) + 1, grub_le_to_cpu64 (dir->data->sb.diroffset) - + grub_le_to_cpu32 (dir->ino.chunk), off); + + grub_le_to_cpu32 (dir->ino.dir.chunk), off); if (err) return 0; @@ -395,7 +408,7 @@ grub_squash_open (struct grub_file *file, const char *name) file->data = data; data->ino = fdiro->ino; - file->size = grub_le_to_cpu32 (fdiro->ino.size); + file->size = grub_le_to_cpu32 (fdiro->ino.file.size); return GRUB_ERR_NONE; } @@ -409,10 +422,10 @@ grub_squash_read_data (struct grub_squash_data *data, grub_uint64_t a, b; int compressed = 0; - if (grub_le_to_cpu16 (ino->fragment) == 0xffff) + if (grub_le_to_cpu16 (ino->file.fragment) == 0xffff) { - if (grub_le_to_cpu32 (ino->chunk)) - a = grub_le_to_cpu32 (ino->chunk); + if (grub_le_to_cpu32 (ino->file.chunk)) + a = grub_le_to_cpu32 (ino->file.chunk); else a = sizeof (struct grub_squash_super); compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_DATA); @@ -422,14 +435,14 @@ grub_squash_read_data (struct grub_squash_data *data, struct grub_squash_frag_desc frag; err = read_chunk (disk, &frag, sizeof (frag), data->fragments, sizeof (frag) - * grub_le_to_cpu16 (ino->fragment)); + * grub_le_to_cpu16 (ino->file.fragment)); if (err) return -1; - a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (ino->chunk); + a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (ino->file.chunk); compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS); } - b = grub_le_to_cpu32 (data->ino.offset) + off; + b = grub_le_to_cpu32 (data->ino.file.offset) + off; /* FIXME: cache uncompressed chunks. */ if (compressed) From e330e4f3830f0c0cab6dfc753c1c9b31c7b909bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 21:17:27 +0100 Subject: [PATCH 035/211] support file mtime --- grub-core/fs/squash4.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 409d91e47..9637496d9 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -351,11 +351,13 @@ grub_squash_dir (grub_device_t device, const char *path, int NESTED_FUNC_ATTR iterate (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node __attribute__ ((unused))) + grub_fshelp_node_t node) { struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtimeset = 1; + info.mtime = grub_le_to_cpu32 (node->ino.mtime); return hook (filename, &info); } From 4a91cd82203200b8c636f4659905449e5ae1395a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 22:29:36 +0100 Subject: [PATCH 036/211] symlink support --- grub-core/fs/squash4.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 9637496d9..95797998a 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -94,6 +94,11 @@ struct grub_squash_inode grub_uint16_t offset; grub_uint16_t dummy3[2]; } dir; + struct { + grub_uint16_t dummy[4]; + grub_uint32_t namelen; + char name[0]; + } symlink; }; } __attribute__ ((packed)); @@ -114,6 +119,7 @@ struct grub_squash_dirent grub_uint16_t type; #define SQUASH_TYPE_DIR 1 #define SQUASH_TYPE_REGULAR 2 +#define SQUASH_TYPE_SYMLINK 3 /* Actually the value is the length of name - 1. */ grub_uint16_t namelen; char name[0]; @@ -141,6 +147,8 @@ struct grub_fshelp_node { struct grub_squash_data *data; struct grub_squash_inode ino; + grub_uint32_t ino_chunk; + grub_uint16_t ino_offset; }; static grub_err_t @@ -251,6 +259,28 @@ squash_mount (grub_disk_t disk) return data; } +static char * +grub_squash_read_symlink (grub_fshelp_node_t node) +{ + char *ret; + grub_err_t err; + ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1); + + err = read_chunk (node->data->disk, ret, + grub_le_to_cpu32 (node->ino.symlink.namelen), + grub_le_to_cpu64 (node->data->sb.inodeoffset) + + node->ino_chunk, + node->ino_offset + (node->ino.symlink.name + - (char *) &node->ino)); + if (err) + { + grub_free (ret); + return NULL; + } + ret[grub_le_to_cpu32 (node->ino.symlink.namelen)] = 0; + return ret; +} + static int grub_squash_iterate_dir (grub_fshelp_node_t dir, int NESTED_FUNC_ATTR @@ -313,11 +343,17 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, buf[grub_le_to_cpu16 (di.namelen) + 1] = 0; if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_DIR) filetype = GRUB_FSHELP_DIR; + if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK) + filetype = GRUB_FSHELP_SYMLINK; + node = grub_malloc (sizeof (*node)); if (! node) return 0; *node = *dir; node->ino = ino; + node->ino_chunk = grub_le_to_cpu32 (dh.ino_chunk); + node->ino_offset = grub_le_to_cpu16 (di.ino_offset); + r = hook (buf, filetype, node); grub_free (buf); @@ -375,7 +411,7 @@ grub_squash_dir (grub_device_t device, const char *path, return err; grub_fshelp_find_file (path, &root, &fdiro, grub_squash_iterate_dir, - NULL, GRUB_FSHELP_DIR); + grub_squash_read_symlink, GRUB_FSHELP_DIR); if (!grub_errno) grub_squash_iterate_dir (fdiro, iterate); @@ -401,7 +437,7 @@ grub_squash_open (struct grub_file *file, const char *name) return err; grub_fshelp_find_file (name, &root, &fdiro, grub_squash_iterate_dir, - NULL, GRUB_FSHELP_REG); + grub_squash_read_symlink, GRUB_FSHELP_REG); if (grub_errno) { grub_free (data); From db64f5b16769168329c3269d5907acca7328de6c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 10 Dec 2010 08:42:40 +0100 Subject: [PATCH 037/211] mtime support for cpio and tar --- grub-core/fs/cpio.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index c087b4f90..486d8215c 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -78,7 +78,7 @@ static grub_dl_t my_mod; static grub_err_t grub_cpio_find_file (struct grub_cpio_data *data, char **name, - grub_uint32_t * ofs) + grub_int32_t *mtime, grub_uint32_t * ofs) { #ifndef MODE_USTAR struct head hd; @@ -91,6 +91,8 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive"); data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2; + if (mtime) + *mtime = (((grub_uint32_t) hd.mtime_1) << 16) + hd.mtime_2; if (hd.namesize & 1) hd.namesize++; @@ -139,6 +141,8 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & ~(GRUB_DISK_SECTOR_SIZE - 1)); + if (mtime) + *mtime = grub_strtoul (hd.mtime, NULL, 8); #endif return GRUB_ERR_NONE; } @@ -204,7 +208,9 @@ grub_cpio_dir (grub_device_t device, const char *path, data->hofs = 0; while (1) { - if (grub_cpio_find_file (data, &name, &ofs)) + grub_int32_t mtime; + + if (grub_cpio_find_file (data, &name, &mtime, &ofs)) goto fail; if (!ofs) @@ -227,6 +233,8 @@ grub_cpio_dir (grub_device_t device, const char *path, struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); info.dir = (p != NULL); + info.mtime = mtime; + info.mtimeset = 1; hook (name + len, &info); if (prev) @@ -269,7 +277,7 @@ grub_cpio_open (grub_file_t file, const char *name) data->hofs = 0; while (1) { - if (grub_cpio_find_file (data, &fn, &ofs)) + if (grub_cpio_find_file (data, &fn, NULL, &ofs)) goto fail; if (!ofs) From a2de6bf6ed9b2e3e4dcc9347f6d780608e11e95c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 10 Dec 2010 10:32:50 +0100 Subject: [PATCH 038/211] filesystem mtime support for iso9660 --- grub-core/fs/iso9660.c | 130 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 6dc465f25..96753ac69 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -27,6 +27,7 @@ #include #include #include +#include #define GRUB_ISO9660_FSTYPE_DIR 0040000 #define GRUB_ISO9660_FSTYPE_REG 0100000 @@ -153,6 +154,108 @@ struct grub_fshelp_node static grub_dl_t my_mod; +#define SECPERMIN 60 +#define SECPERHOUR (60*SECPERMIN) +#define SECPERDAY (24*SECPERHOUR) +#define SECPERYEAR (365*SECPERDAY) +#define SECPER4YEARS (4*SECPERYEAR+SECPERDAY) + +static grub_err_t +grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) +{ + grub_int32_t ret; + int y4, ay; + grub_uint16_t monthssum[12] + = { 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30}; + grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + if (datetime->year > 2038 || datetime->year < 1902) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "outside of UNIX epoch"); + if (datetime->month > 12 || datetime->month < 1) + return grub_error (GRUB_ERR_BAD_NUMBER, "not a valid month"); + + /* In the period of validity of unixtime all years divisible by 4 + are bissextile*/ + /* Convenience: let's have 3 consecutive non-bissextile years + at the beginning of the epoch. So count from 1973 instead of 1970 */ + ret = 3*SECPERYEAR + SECPERDAY; + + /* Transform C divisions and modulos to mathematical ones */ + y4 = (datetime->year - 1973) / 4; + if (datetime->year < 1973) + y4--; + ay = datetime->year - 1973 - 4 * y4; + ret += y4 * SECPER4YEARS; + ret += ay * SECPERYEAR; + + ret += monthssum[datetime->month - 1] * SECPERDAY; + if (ay == 0 && datetime->month >= 3) + ret += SECPERDAY; + + ret += (datetime->day - 1) * SECPERDAY; + if ((datetime->day > months[datetime->month - 1] + && (!ay || datetime->month != 2 || datetime->day != 29)) + || datetime->day < 1) + return grub_error (GRUB_ERR_BAD_NUMBER, "invalid day"); + + ret += datetime->hour * SECPERHOUR; + if (datetime->hour > 23) + return grub_error (GRUB_ERR_BAD_NUMBER, "invalid hour"); + ret += datetime->minute * 60; + if (datetime->minute > 59) + return grub_error (GRUB_ERR_BAD_NUMBER, "invalid minute"); + + ret += datetime->second; + /* Accept leap seconds. */ + if (datetime->second > 60) + return grub_error (GRUB_ERR_BAD_NUMBER, "invalid second"); + + if ((datetime->year > 1980 && ret < 0) + || (datetime->year < 1960 && ret > 0)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "outside of UNIX epoch"); + *nix = ret; + return GRUB_ERR_NONE; +} + +static grub_err_t +iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) +{ + grub_err_t err; + struct grub_datetime datetime; + + if (! i->year[0] && ! i->year[1] + && ! i->year[2] && ! i->year[3] + && ! i->month[0] && ! i->month[1] + && ! i->day[0] && ! i->day[1] + && ! i->hour[0] && ! i->hour[1] + && ! i->minute[0] && ! i->minute[1] + && ! i->second[0] && ! i->second[1] + && ! i->hundredth[0] && ! i->hundredth[1]) + return grub_error (GRUB_ERR_BAD_NUMBER, "empty date"); + datetime.year = (i->year[0] - '0') * 1000 + (i->year[1] - '0') * 100 + + (i->year[2] - '0') * 10 + (i->year[3] - '0'); + datetime.month = (i->month[0] - '0') * 10 + (i->month[1] - '0'); + datetime.day = (i->day[0] - '0') * 10 + (i->day[1] - '0'); + datetime.hour = (i->hour[0] - '0') * 10 + (i->hour[1] - '0'); + datetime.minute = (i->minute[0] - '0') * 10 + (i->minute[1] - '0'); + datetime.second = (i->second[0] - '0') * 10 + (i->second[1] - '0'); + + err = grub_datetime2unixtime (&datetime, nix); + *nix -= i->offset * 60 * 15; + return err; +} + /* Iterate over the susp entries, starting with block SUA_BLOCK on the offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for every entry. */ @@ -871,6 +974,32 @@ grub_iso9660_uuid (grub_device_t device, char **uuid) return grub_errno; } +/* Get writing time of filesystem. */ +static grub_err_t +grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf) +{ + struct grub_iso9660_data *data; + grub_disk_t disk = device->disk; + grub_err_t err; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (disk); + if (!data) + { + grub_dl_unref (my_mod); + return grub_errno; + } + err = iso9660_to_unixtime (&data->voldesc.modified, timebuf); + + grub_dl_unref (my_mod); + + grub_free (data); + + return err; +} + + static struct grub_fs grub_iso9660_fs = @@ -882,6 +1011,7 @@ static struct grub_fs grub_iso9660_fs = .close = grub_iso9660_close, .label = grub_iso9660_label, .uuid = grub_iso9660_uuid, + .mtime = grub_iso9660_mtime, .next = 0 }; From c50d99c5e531a6a7cedebd6de51d98fcfda5f694 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 10 Dec 2010 11:12:59 +0100 Subject: [PATCH 039/211] file mtime support for iso9660 --- grub-core/fs/iso9660.c | 60 +++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 96753ac69..03bfd3e92 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -54,6 +54,17 @@ struct grub_iso9660_voldesc grub_uint8_t version; } __attribute__ ((packed)); +struct grub_iso9660_date2 +{ + grub_uint8_t year; + grub_uint8_t month; + grub_uint8_t day; + grub_uint8_t hour; + grub_uint8_t minute; + grub_uint8_t second; + grub_uint8_t offset; +} __attribute__ ((packed)); + /* A directory entry. */ struct grub_iso9660_dir { @@ -63,7 +74,7 @@ struct grub_iso9660_dir grub_uint32_t first_sector_be; grub_uint32_t size; grub_uint32_t size_be; - grub_uint8_t unused1[7]; + struct grub_iso9660_date2 mtime; grub_uint8_t flags; grub_uint8_t unused2[6]; grub_uint8_t namelen; @@ -145,6 +156,7 @@ struct grub_iso9660_data struct grub_fshelp_node { struct grub_iso9660_data *data; + struct grub_iso9660_dir dirent; unsigned int size; unsigned int blk; unsigned int dir_blk; @@ -188,14 +200,14 @@ grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) /* In the period of validity of unixtime all years divisible by 4 are bissextile*/ /* Convenience: let's have 3 consecutive non-bissextile years - at the beginning of the epoch. So count from 1973 instead of 1970 */ - ret = 3*SECPERYEAR + SECPERDAY; + at the beginning of the epoch. So count from 1971 instead of 1970 */ + ret = SECPERYEAR + SECPERDAY; /* Transform C divisions and modulos to mathematical ones */ - y4 = (datetime->year - 1973) / 4; - if (datetime->year < 1973) + y4 = (datetime->year - 1971) / 4; + if (datetime->year < 1971) y4--; - ay = datetime->year - 1973 - 4 * y4; + ay = datetime->year - 1971 - 4 * y4; ret += y4 * SECPER4YEARS; ret += ay * SECPERYEAR; @@ -256,6 +268,24 @@ iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) return err; } +static grub_err_t +iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) +{ + grub_err_t err; + struct grub_datetime datetime; + + datetime.year = i->year + 1900; + datetime.month = i->month; + datetime.day = i->day; + datetime.hour = i->hour; + datetime.minute = i->minute; + datetime.second = i->second; + + err = grub_datetime2unixtime (&datetime, nix); + *nix -= i->offset * 60 * 15; + return err; +} + /* Iterate over the susp entries, starting with block SUA_BLOCK on the offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for every entry. */ @@ -467,7 +497,6 @@ grub_iso9660_mount (grub_disk_t disk) static char * grub_iso9660_read_symlink (grub_fshelp_node_t node) { - struct grub_iso9660_dir dirent; int sua_off; int sua_size; char *symlink = 0; @@ -545,13 +574,10 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node) return 0; } - if (grub_disk_read (node->data->disk, node->dir_blk, node->dir_off, - sizeof (dirent), (char *) &dirent)) - return 0; - - sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2) + sua_off = (sizeof (node->dirent) + node->dirent.namelen + 1 + - (node->dirent.namelen % 2) + node->data->susp_skip); - sua_size = dirent.len - sua_off; + sua_size = node->dirent.len - sua_off; symlink = grub_malloc (1); if (!symlink) @@ -748,6 +774,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, filename_alloc = 1; } + node->dirent = dirent; if (hook (filename, type, node)) { if (filename_alloc) @@ -784,8 +811,15 @@ grub_iso9660_dir (grub_device_t device, const char *path, grub_fshelp_node_t node) { struct grub_dirhook_info info; + grub_err_t err; grub_memset (&info, 0, sizeof (info)); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + err = iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime); + if (err) + grub_errno = GRUB_ERR_NONE; + else + info.mtimeset = 1; + grub_free (node); return hook (filename, &info); } From 3b95531920bdd3bd96706ef6fb01ee6a0cfab8f1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 10 Dec 2010 15:04:12 +0100 Subject: [PATCH 040/211] fix unix range --- grub-core/fs/iso9660.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 03bfd3e92..3b0da5e53 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -192,7 +192,7 @@ grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30}; grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - if (datetime->year > 2038 || datetime->year < 1902) + if (datetime->year > 2038 || datetime->year < 1901) return grub_error (GRUB_ERR_OUT_OF_RANGE, "outside of UNIX epoch"); if (datetime->month > 12 || datetime->month < 1) return grub_error (GRUB_ERR_BAD_NUMBER, "not a valid month"); From 5706da04438db67180e6b08a3f62aa4ba0b58b75 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 10 Dec 2010 16:19:24 +0100 Subject: [PATCH 041/211] mtime support for xfs --- grub-core/fs/xfs.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 9dffe31d1..966bade1b 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -98,13 +98,22 @@ struct grub_xfs_btree_root grub_uint64_t keys[1]; } __attribute__ ((packed)); +struct grub_xfs_time +{ + grub_uint32_t sec; + grub_uint32_t nanosec; +} __attribute__ ((packed)); + struct grub_xfs_inode { grub_uint8_t magic[2]; grub_uint16_t mode; grub_uint8_t version; grub_uint8_t format; - grub_uint8_t unused2[50]; + grub_uint8_t unused2[26]; + struct grub_xfs_time atime; + struct grub_xfs_time mtime; + struct grub_xfs_time ctime; grub_uint64_t size; grub_uint64_t nblocks; grub_uint32_t extsize; @@ -643,6 +652,11 @@ grub_xfs_dir (grub_device_t device, const char *path, { struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); + if (node->inode_read) + { + info.mtimeset = 1; + info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec); + } info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); return hook (filename, &info); From f22c12e8524f69b3482f6965d8d9b3480b8a9588 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 10 Dec 2010 17:37:32 +0100 Subject: [PATCH 042/211] mtime for UDF support --- grub-core/fs/iso9660.c | 97 ++++------------------------------------- grub-core/fs/udf.c | 29 ++++++++++++ include/grub/datetime.h | 73 +++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 88 deletions(-) diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 3b0da5e53..f2f4b5a97 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -166,84 +166,9 @@ struct grub_fshelp_node static grub_dl_t my_mod; -#define SECPERMIN 60 -#define SECPERHOUR (60*SECPERMIN) -#define SECPERDAY (24*SECPERHOUR) -#define SECPERYEAR (365*SECPERDAY) -#define SECPER4YEARS (4*SECPERYEAR+SECPERDAY) - -static grub_err_t -grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) -{ - grub_int32_t ret; - int y4, ay; - grub_uint16_t monthssum[12] - = { 0, - 31, - 31 + 28, - 31 + 28 + 31, - 31 + 28 + 31 + 30, - 31 + 28 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30}; - grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - - if (datetime->year > 2038 || datetime->year < 1901) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "outside of UNIX epoch"); - if (datetime->month > 12 || datetime->month < 1) - return grub_error (GRUB_ERR_BAD_NUMBER, "not a valid month"); - - /* In the period of validity of unixtime all years divisible by 4 - are bissextile*/ - /* Convenience: let's have 3 consecutive non-bissextile years - at the beginning of the epoch. So count from 1971 instead of 1970 */ - ret = SECPERYEAR + SECPERDAY; - - /* Transform C divisions and modulos to mathematical ones */ - y4 = (datetime->year - 1971) / 4; - if (datetime->year < 1971) - y4--; - ay = datetime->year - 1971 - 4 * y4; - ret += y4 * SECPER4YEARS; - ret += ay * SECPERYEAR; - - ret += monthssum[datetime->month - 1] * SECPERDAY; - if (ay == 0 && datetime->month >= 3) - ret += SECPERDAY; - - ret += (datetime->day - 1) * SECPERDAY; - if ((datetime->day > months[datetime->month - 1] - && (!ay || datetime->month != 2 || datetime->day != 29)) - || datetime->day < 1) - return grub_error (GRUB_ERR_BAD_NUMBER, "invalid day"); - - ret += datetime->hour * SECPERHOUR; - if (datetime->hour > 23) - return grub_error (GRUB_ERR_BAD_NUMBER, "invalid hour"); - ret += datetime->minute * 60; - if (datetime->minute > 59) - return grub_error (GRUB_ERR_BAD_NUMBER, "invalid minute"); - - ret += datetime->second; - /* Accept leap seconds. */ - if (datetime->second > 60) - return grub_error (GRUB_ERR_BAD_NUMBER, "invalid second"); - - if ((datetime->year > 1980 && ret < 0) - || (datetime->year < 1960 && ret > 0)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "outside of UNIX epoch"); - *nix = ret; - return GRUB_ERR_NONE; -} - static grub_err_t iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) { - grub_err_t err; struct grub_datetime datetime; if (! i->year[0] && ! i->year[1] @@ -263,17 +188,17 @@ iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) datetime.minute = (i->minute[0] - '0') * 10 + (i->minute[1] - '0'); datetime.second = (i->second[0] - '0') * 10 + (i->second[1] - '0'); - err = grub_datetime2unixtime (&datetime, nix); + if (!grub_datetime2unixtime (&datetime, nix)) + return grub_error (GRUB_ERR_BAD_NUMBER, "incorrect date"); *nix -= i->offset * 60 * 15; - return err; + return GRUB_ERR_NONE; } -static grub_err_t +static int iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) { - grub_err_t err; struct grub_datetime datetime; - + datetime.year = i->year + 1900; datetime.month = i->month; datetime.day = i->day; @@ -281,9 +206,10 @@ iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) datetime.minute = i->minute; datetime.second = i->second; - err = grub_datetime2unixtime (&datetime, nix); + if (!grub_datetime2unixtime (&datetime, nix)) + return 0; *nix -= i->offset * 60 * 15; - return err; + return 1; } /* Iterate over the susp entries, starting with block SUA_BLOCK on the @@ -811,14 +737,9 @@ grub_iso9660_dir (grub_device_t device, const char *path, grub_fshelp_node_t node) { struct grub_dirhook_info info; - grub_err_t err; grub_memset (&info, 0, sizeof (info)); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - err = iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime); - if (err) - grub_errno = GRUB_ERR_NONE; - else - info.mtimeset = 1; + info.mtimeset = !!iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime); grub_free (node); return hook (filename, &info); diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 7041e619e..0c5da996e 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -26,6 +26,7 @@ #include #include #include +#include #define GRUB_UDF_MAX_PDS 2 #define GRUB_UDF_MAX_PMS 6 @@ -904,8 +905,36 @@ grub_udf_dir (grub_device_t device, const char *path, grub_fshelp_node_t node) { struct grub_dirhook_info info; + const struct grub_udf_timestamp *tstamp = NULL; grub_memset (&info, 0, sizeof (info)); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) + tstamp = &node->fe.modification_time; + else if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_EFE) + tstamp = &node->efe.modification_time; + + if (tstamp && (U16 (tstamp->type_and_timezone) & 0xf000) == 0x1000) + { + grub_int16_t tz; + struct grub_datetime datetime; + + datetime.year = U16 (tstamp->year); + datetime.month = tstamp->month; + datetime.day = tstamp->day; + datetime.hour = tstamp->hour; + datetime.minute = tstamp->minute; + datetime.second = tstamp->second; + + tz = U16 (tstamp->type_and_timezone) & 0xfff; + if (tz & 0x800) + tz |= 0xf000; + if (tz == -2047) + tz = 0; + + info.mtimeset = !!grub_datetime2unixtime (&datetime, &info.mtime); + + info.mtime -= 60 * tz; + } grub_free (node); return hook (filename, &info); } diff --git a/include/grub/datetime.h b/include/grub/datetime.h index e721e89af..c20fc8c36 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -51,5 +51,78 @@ char *grub_get_weekday_name (struct grub_datetime *datetime); void grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime); +static inline int +grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) +{ + grub_int32_t ret; + int y4, ay; + const grub_uint16_t monthssum[12] + = { 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30}; + const grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, + 31, 31, 30, 31, 30, 31}; + const int SECPERMIN = 60; + const int SECPERHOUR = 60 * SECPERMIN; + const int SECPERDAY = 24 * SECPERHOUR; + const int SECPERYEAR = 365 * SECPERDAY; + const int SECPER4YEARS = 4 * SECPERYEAR + SECPERDAY; + + if (datetime->year > 2038 || datetime->year < 1901) + return 0; + if (datetime->month > 12 || datetime->month < 1) + return 0; + + /* In the period of validity of unixtime all years divisible by 4 + are bissextile*/ + /* Convenience: let's have 3 consecutive non-bissextile years + at the beginning of the epoch. So count from 1971 instead of 1970 */ + ret = SECPERYEAR + SECPERDAY; + + /* Transform C divisions and modulos to mathematical ones */ + y4 = (datetime->year - 1971) / 4; + if (datetime->year < 1971) + y4--; + ay = datetime->year - 1971 - 4 * y4; + ret += y4 * SECPER4YEARS; + ret += ay * SECPERYEAR; + + ret += monthssum[datetime->month - 1] * SECPERDAY; + if (ay == 0 && datetime->month >= 3) + ret += SECPERDAY; + + ret += (datetime->day - 1) * SECPERDAY; + if ((datetime->day > months[datetime->month - 1] + && (!ay || datetime->month != 2 || datetime->day != 29)) + || datetime->day < 1) + return 0; + + ret += datetime->hour * SECPERHOUR; + if (datetime->hour > 23) + return 0; + ret += datetime->minute * 60; + if (datetime->minute > 59) + return 0; + + ret += datetime->second; + /* Accept leap seconds. */ + if (datetime->second > 60) + return 0; + + if ((datetime->year > 1980 && ret < 0) + || (datetime->year < 1960 && ret > 0)) + return 0; + *nix = ret; + return 1; +} #endif /* ! KERNEL_DATETIME_HEADER */ From 52832c554c3f4393819ad8fc67a92efc85fc8562 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 10 Dec 2010 16:45:58 +0000 Subject: [PATCH 043/211] Move gfxmenu color handling to video, so that gfxterm can use it too. * grub-core/gfxmenu/named_colors.c: Move to ... * grub-core/video/colors.c: ... here. Rename grub_gui_get_named_color to grub_video_get_named_color. * grub-core/gfxmenu/gui_string_util.c (my_isxdigit): Move to ... * grub-core/video/colors.c (my_isxdigit): ... here. * grub-core/gfxmenu/gui_string_util.c (parse_hex_color_component): Move to ... * grub-core/video/colors.c (parse_hex_color_component): ... here. * grub-core/gfxmenu/gui_string_util.c (grub_gui_parse_color): Move to ... * grub-core/video/colors.c (grub_video_parse_color): ... here. * include/grub/gui.h (grub_gui_color_t): Move to ... * include/grub/video.h (grub_video_rgba_color_t): ... here. * include/grub/gui.h (grub_gui_color_rgb): Move to ... * include/grub/video.h (grub_video_rgba_color_rgb): ... here. * include/grub/gui.h (grub_gui_map_color): Move to ... * include/grub/video.h (grub_video_map_rgba_color): ... here. * include/grub/gui_string_util.h (grub_gui_get_named_color): Move to ... * include/grub/video.h (grub_video_get_named_color): ... here. * include/grub/gui_string_util.h (grub_gui_parse_color): Move to ... * include/grub/video.h (grub_video_parse_color): ... here. * grub-core/Makefile.core.def (kernel) [videoinkernel]: Add video/colors.c. (gfxmenu): Remove gfxmenu/named_colors.c. (video_colors) [videomodules]: New module, containing video/colors.c. --- ChangeLog.parse-color | 34 +++++ grub-core/Makefile.core.def | 8 +- grub-core/gfxmenu/gui_label.c | 6 +- grub-core/gfxmenu/gui_list.c | 16 +-- grub-core/gfxmenu/gui_progress_bar.c | 31 ++--- grub-core/gfxmenu/gui_string_util.c | 121 ----------------- grub-core/gfxmenu/theme_loader.c | 8 +- grub-core/gfxmenu/view.c | 16 +-- .../named_colors.c => video/colors.c} | 127 +++++++++++++++++- include/grub/gfxmenu_view.h | 8 +- include/grub/gui.h | 27 ---- include/grub/gui_string_util.h | 4 - include/grub/video.h | 32 +++++ 13 files changed, 240 insertions(+), 198 deletions(-) create mode 100644 ChangeLog.parse-color rename grub-core/{gfxmenu/named_colors.c => video/colors.c} (70%) diff --git a/ChangeLog.parse-color b/ChangeLog.parse-color new file mode 100644 index 000000000..93d696c6c --- /dev/null +++ b/ChangeLog.parse-color @@ -0,0 +1,34 @@ +2010-12-10 Colin Watson + + Move gfxmenu color handling to video, so that gfxterm can use it + too. + + * grub-core/gfxmenu/named_colors.c: Move to ... + * grub-core/video/colors.c: ... here. Rename + grub_gui_get_named_color to grub_video_get_named_color. + * grub-core/gfxmenu/gui_string_util.c (my_isxdigit): Move to ... + * grub-core/video/colors.c (my_isxdigit): ... here. + * grub-core/gfxmenu/gui_string_util.c (parse_hex_color_component): + Move to ... + * grub-core/video/colors.c (parse_hex_color_component): ... here. + * grub-core/gfxmenu/gui_string_util.c (grub_gui_parse_color): Move + to ... + * grub-core/video/colors.c (grub_video_parse_color): ... here. + + * include/grub/gui.h (grub_gui_color_t): Move to ... + * include/grub/video.h (grub_video_rgba_color_t): ... here. + * include/grub/gui.h (grub_gui_color_rgb): Move to ... + * include/grub/video.h (grub_video_rgba_color_rgb): ... here. + * include/grub/gui.h (grub_gui_map_color): Move to ... + * include/grub/video.h (grub_video_map_rgba_color): ... here. + * include/grub/gui_string_util.h (grub_gui_get_named_color): Move + to ... + * include/grub/video.h (grub_video_get_named_color): ... here. + * include/grub/gui_string_util.h (grub_gui_parse_color): Move to ... + * include/grub/video.h (grub_video_parse_color): ... here. + + * grub-core/Makefile.core.def (kernel) [videoinkernel]: Add + video/colors.c. + (gfxmenu): Remove gfxmenu/named_colors.c. + (video_colors) [videomodules]: New module, containing + video/colors.c. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 37c0ce970..fdf7d0826 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -178,6 +178,7 @@ kernel = { videoinkernel = io/bufio.c; videoinkernel = video/bitmap.c; videoinkernel = video/bitmap_scale.c; + videoinkernel = video/colors.c; videoinkernel = video/fb/fbblit.c; videoinkernel = video/fb/fbfill.c; videoinkernel = video/fb/fbutil.c; @@ -1049,7 +1050,6 @@ module = { common = gfxmenu/gui_progress_bar.c; common = gfxmenu/gui_util.c; common = gfxmenu/gui_string_util.c; - common = gfxmenu/named_colors.c; }; module = { @@ -1442,6 +1442,12 @@ module = { enable = i386_pc; }; +module = { + name = video_colors; + common = video/colors.c; + enable = videomodules; +}; + module = { name = video_fb; common = video/fb/video_fb.c; diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c index 15a352f84..a7dc95afc 100644 --- a/grub-core/gfxmenu/gui_label.c +++ b/grub-core/gfxmenu/gui_label.c @@ -48,7 +48,7 @@ struct grub_gui_label char *text; char *template; grub_font_t font; - grub_gui_color_t color; + grub_video_rgba_color_t color; int value; enum align_mode align; }; @@ -107,7 +107,7 @@ label_paint (void *vself, const grub_video_rect_t *region) grub_gui_set_viewport (&self->bounds, &vpsave); grub_font_draw_string (self->text, self->font, - grub_gui_map_color (self->color), + grub_video_map_rgba_color (self->color), left_x, grub_font_get_ascent (self->font)); grub_gui_restore_viewport (&vpsave); @@ -186,7 +186,7 @@ label_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "color") == 0) { - grub_gui_parse_color (value, &self->color); + grub_video_parse_color (value, &self->color); } else if (grub_strcmp (name, "align") == 0) { diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c index b6b07dfd6..ca2061795 100644 --- a/grub-core/gfxmenu/gui_list.c +++ b/grub-core/gfxmenu/gui_list.c @@ -41,9 +41,9 @@ struct grub_gui_list_impl int item_spacing; grub_font_t item_font; grub_font_t selected_item_font; - grub_gui_color_t item_color; + grub_video_rgba_color_t item_color; int selected_item_color_set; - grub_gui_color_t selected_item_color; + grub_video_rgba_color_t selected_item_color; int draw_scrollbar; int need_to_recreate_scrollbar; @@ -267,13 +267,13 @@ draw_menu (list_impl_t self, int num_shown_items) (is_selected && self->selected_item_font ? self->selected_item_font : self->item_font); - grub_gui_color_t text_color = + grub_video_rgba_color_t text_color = ((is_selected && self->selected_item_color_set) ? self->selected_item_color : self->item_color); grub_font_draw_string (item_title, font, - grub_gui_map_color (text_color), + grub_video_map_rgba_color (text_color), sel_leftpad + self->icon_width + icon_text_space, (item_top + (item_height - (ascent + descent)) / 2 + ascent)); @@ -429,7 +429,7 @@ list_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "item_color") == 0) { - grub_gui_parse_color (value, &self->item_color); + grub_video_parse_color (value, &self->item_color); } else if (grub_strcmp (name, "selected_item_color") == 0) { @@ -439,7 +439,7 @@ list_set_property (void *vself, const char *name, const char *value) } else { - if (grub_gui_parse_color (value, &self->selected_item_color) + if (grub_video_parse_color (value, &self->selected_item_color) == GRUB_ERR_NONE) self->selected_item_color_set = 1; } @@ -562,7 +562,7 @@ grub_gui_list_new (void) { list_impl_t self; grub_font_t default_font; - grub_gui_color_t default_fg_color; + grub_video_rgba_color_t default_fg_color; self = grub_zalloc (sizeof (*self)); if (! self) @@ -574,7 +574,7 @@ grub_gui_list_new (void) self->visible = 1; default_font = grub_font_get ("Unknown Regular 16"); - default_fg_color = grub_gui_color_rgb (0, 0, 0); + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); self->icon_width = 32; self->icon_height = 32; diff --git a/grub-core/gfxmenu/gui_progress_bar.c b/grub-core/gfxmenu/gui_progress_bar.c index e1b31794f..db89ccbf7 100644 --- a/grub-core/gfxmenu/gui_progress_bar.c +++ b/grub-core/gfxmenu/gui_progress_bar.c @@ -40,10 +40,10 @@ struct grub_gui_progress_bar int show_text; char *template; grub_font_t font; - grub_gui_color_t text_color; - grub_gui_color_t border_color; - grub_gui_color_t bg_color; - grub_gui_color_t fg_color; + grub_video_rgba_color_t text_color; + grub_video_rgba_color_t border_color; + grub_video_rgba_color_t bg_color; + grub_video_rgba_color_t fg_color; char *theme_dir; int need_to_recreate_pixmaps; @@ -109,7 +109,7 @@ draw_filled_rect_bar (grub_gui_progress_bar_t self) f.height = self->bounds.height - 2; /* Border. */ - grub_video_fill_rect (grub_gui_map_color (self->border_color), + grub_video_fill_rect (grub_video_map_rgba_color (self->border_color), f.x - 1, f.y - 1, f.width + 2, f.height + 2); @@ -117,12 +117,12 @@ draw_filled_rect_bar (grub_gui_progress_bar_t self) int barwidth = (f.width * (self->value - self->start) / (self->end - self->start)); - grub_video_fill_rect (grub_gui_map_color (self->bg_color), + grub_video_fill_rect (grub_video_map_rgba_color (self->bg_color), f.x + barwidth, f.y, f.width - barwidth, f.height); /* Bar foreground. */ - grub_video_fill_rect (grub_gui_map_color (self->fg_color), + grub_video_fill_rect (grub_video_map_rgba_color (self->fg_color), f.x, f.y, barwidth, f.height); } @@ -161,7 +161,8 @@ draw_text (grub_gui_progress_bar_t self) if (self->template) { grub_font_t font = self->font; - grub_video_color_t text_color = grub_gui_map_color (self->text_color); + grub_video_color_t text_color = + grub_video_map_rgba_color (self->text_color); int width = self->bounds.width; int height = self->bounds.height; char *text; @@ -298,19 +299,19 @@ progress_bar_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "text_color") == 0) { - grub_gui_parse_color (value, &self->text_color); + grub_video_parse_color (value, &self->text_color); } else if (grub_strcmp (name, "border_color") == 0) { - grub_gui_parse_color (value, &self->border_color); + grub_video_parse_color (value, &self->border_color); } else if (grub_strcmp (name, "bg_color") == 0) { - grub_gui_parse_color (value, &self->bg_color); + grub_video_parse_color (value, &self->bg_color); } else if (grub_strcmp (name, "fg_color") == 0) { - grub_gui_parse_color (value, &self->fg_color); + grub_video_parse_color (value, &self->fg_color); } else if (grub_strcmp (name, "bar_style") == 0) { @@ -379,9 +380,9 @@ grub_gui_progress_bar_new (void) self->progress.component.ops = &progress_bar_ops; self->visible = 1; self->font = grub_font_get ("Unknown Regular 16"); - grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; - grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; - grub_gui_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; + grub_video_rgba_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; + grub_video_rgba_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; + grub_video_rgba_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; self->text_color = black; self->border_color = black; self->bg_color = gray; diff --git a/grub-core/gfxmenu/gui_string_util.c b/grub-core/gfxmenu/gui_string_util.c index 8c51e396a..a9a415e31 100644 --- a/grub-core/gfxmenu/gui_string_util.c +++ b/grub-core/gfxmenu/gui_string_util.c @@ -204,124 +204,3 @@ grub_get_dirname (const char *file_path) return grub_new_substring (file_path, 0, last_slash + 1); } - -static __inline int -my_isxdigit (char c) -{ - return ((c >= '0' && c <= '9') - || (c >= 'a' && c <= 'f') - || (c >= 'A' && c <= 'F')); -} - -static int -parse_hex_color_component (const char *s, unsigned start, unsigned end) -{ - unsigned len; - char buf[3]; - - len = end - start; - /* Check the limits so we don't overrun the buffer. */ - if (len < 1 || len > 2) - return 0; - - if (len == 1) - { - buf[0] = s[start]; /* Get the first and only hex digit. */ - buf[1] = buf[0]; /* Duplicate the hex digit. */ - } - else if (len == 2) - { - buf[0] = s[start]; - buf[1] = s[start + 1]; - } - - buf[2] = '\0'; - - return grub_strtoul (buf, 0, 16); -} - -/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA", - "#RRGGBB", or "#RRGGBBAA". */ -grub_err_t -grub_gui_parse_color (const char *s, grub_gui_color_t *color) -{ - grub_gui_color_t c; - - /* Skip whitespace. */ - while (*s && grub_isspace (*s)) - s++; - - if (*s == '#') - { - /* HTML-style. Number if hex digits: - [6] #RRGGBB [3] #RGB - [8] #RRGGBBAA [4] #RGBA */ - - s++; /* Skip the '#'. */ - /* Count the hexits to determine the format. */ - int hexits = 0; - const char *end = s; - while (my_isxdigit (*end)) - { - end++; - hexits++; - } - - /* Parse the color components based on the format. */ - if (hexits == 3 || hexits == 4) - { - c.red = parse_hex_color_component (s, 0, 1); - c.green = parse_hex_color_component (s, 1, 2); - c.blue = parse_hex_color_component (s, 2, 3); - if (hexits == 4) - c.alpha = parse_hex_color_component (s, 3, 4); - else - c.alpha = 255; - } - else if (hexits == 6 || hexits == 8) - { - c.red = parse_hex_color_component (s, 0, 2); - c.green = parse_hex_color_component (s, 2, 4); - c.blue = parse_hex_color_component (s, 4, 6); - if (hexits == 8) - c.alpha = parse_hex_color_component (s, 6, 8); - else - c.alpha = 255; - } - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "invalid HTML-type color string `%s'", s); - } - else if (grub_isdigit (*s)) - { - /* Comma separated decimal values. */ - c.red = grub_strtoul (s, 0, 0); - if ((s = grub_strchr (s, ',')) == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "missing 1st comma separator in color `%s'", s); - s++; - c.green = grub_strtoul (s, 0, 0); - if ((s = grub_strchr (s, ',')) == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "missing 2nd comma separator in color `%s'", s); - s++; - c.blue = grub_strtoul (s, 0, 0); - if ((s = grub_strchr (s, ',')) == 0) - c.alpha = 255; - else - { - s++; - c.alpha = grub_strtoul (s, 0, 0); - } - } - else - { - if (! grub_gui_get_named_color (s, &c)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "invalid named color `%s'", s); - } - - if (grub_errno == GRUB_ERR_NONE) - *color = c; - return grub_errno; -} diff --git a/grub-core/gfxmenu/theme_loader.c b/grub-core/gfxmenu/theme_loader.c index 3854c6c53..f9c711d3e 100644 --- a/grub-core/gfxmenu/theme_loader.c +++ b/grub-core/gfxmenu/theme_loader.c @@ -135,11 +135,11 @@ theme_set_string (grub_gfxmenu_view_t view, return grub_errno; } else if (! grub_strcmp ("title-color", name)) - grub_gui_parse_color (value, &view->title_color); + grub_video_parse_color (value, &view->title_color); else if (! grub_strcmp ("message-color", name)) - grub_gui_parse_color (value, &view->message_color); + grub_video_parse_color (value, &view->message_color); else if (! grub_strcmp ("message-bg-color", name)) - grub_gui_parse_color (value, &view->message_bg_color); + grub_video_parse_color (value, &view->message_bg_color); else if (! grub_strcmp ("desktop-image", name)) { struct grub_video_bitmap *raw_bitmap; @@ -170,7 +170,7 @@ theme_set_string (grub_gfxmenu_view_t view, view->desktop_image = scaled_bitmap; } else if (! grub_strcmp ("desktop-color", name)) - grub_gui_parse_color (value, &view->desktop_color); + grub_video_parse_color (value, &view->desktop_color); else if (! grub_strcmp ("terminal-box", name)) { grub_err_t err; diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c index 901cdc889..836a9884d 100644 --- a/grub-core/gfxmenu/view.c +++ b/grub-core/gfxmenu/view.c @@ -50,8 +50,8 @@ grub_gfxmenu_view_new (const char *theme_path, { grub_gfxmenu_view_t view; grub_font_t default_font; - grub_gui_color_t default_fg_color; - grub_gui_color_t default_bg_color; + grub_video_rgba_color_t default_fg_color; + grub_video_rgba_color_t default_bg_color; view = grub_malloc (sizeof (*view)); if (! view) @@ -63,8 +63,8 @@ grub_gfxmenu_view_new (const char *theme_path, view->screen.height = height; default_font = grub_font_get ("Unknown Regular 16"); - default_fg_color = grub_gui_color_rgb (0, 0, 0); - default_bg_color = grub_gui_color_rgb (255, 255, 255); + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); + default_bg_color = grub_video_rgba_color_rgb (255, 255, 255); view->canvas = 0; @@ -131,7 +131,7 @@ redraw_background (grub_gfxmenu_view_t view, } else { - grub_video_fill_rect (grub_gui_map_color (view->desktop_color), + grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color), bounds->x, bounds->y, bounds->width, bounds->height); } @@ -150,7 +150,7 @@ draw_title (grub_gfxmenu_view_t view) int y = 40 + grub_font_get_ascent (view->title_font); grub_font_draw_string (view->title_text, view->title_font, - grub_gui_map_color (view->title_color), + grub_video_map_rgba_color (view->title_color), x, y); } @@ -244,13 +244,13 @@ draw_message (grub_gfxmenu_view_t view) return; grub_font_t font = view->message_font; - grub_video_color_t color = grub_gui_map_color (view->message_color); + grub_video_color_t color = grub_video_map_rgba_color (view->message_color); /* Border. */ grub_video_fill_rect (color, f.x-1, f.y-1, f.width+2, f.height+2); /* Fill. */ - grub_video_fill_rect (grub_gui_map_color (view->message_bg_color), + grub_video_fill_rect (grub_video_map_rgba_color (view->message_bg_color), f.x, f.y, f.width, f.height); /* Center the text. */ diff --git a/grub-core/gfxmenu/named_colors.c b/grub-core/video/colors.c similarity index 70% rename from grub-core/gfxmenu/named_colors.c rename to grub-core/video/colors.c index eedbc47fb..0637c5508 100644 --- a/grub-core/gfxmenu/named_colors.c +++ b/grub-core/video/colors.c @@ -25,7 +25,7 @@ struct named_color { const char *name; - grub_gui_color_t color; + grub_video_rgba_color_t color; }; /* @@ -193,8 +193,8 @@ static struct named_color named_colors[] = stores the color into *COLOR. If the color was not found, returns 0 and does not modify *COLOR. */ int -grub_gui_get_named_color (const char *name, - grub_gui_color_t *color) +grub_video_get_named_color (const char *name, + grub_video_rgba_color_t *color) { int i; for (i = 0; named_colors[i].name; i++) @@ -207,3 +207,124 @@ grub_gui_get_named_color (const char *name, } return 0; } + +static __inline int +my_isxdigit (char c) +{ + return ((c >= '0' && c <= '9') + || (c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F')); +} + +static int +parse_hex_color_component (const char *s, unsigned start, unsigned end) +{ + unsigned len; + char buf[3]; + + len = end - start; + /* Check the limits so we don't overrun the buffer. */ + if (len < 1 || len > 2) + return 0; + + if (len == 1) + { + buf[0] = s[start]; /* Get the first and only hex digit. */ + buf[1] = buf[0]; /* Duplicate the hex digit. */ + } + else if (len == 2) + { + buf[0] = s[start]; + buf[1] = s[start + 1]; + } + + buf[2] = '\0'; + + return grub_strtoul (buf, 0, 16); +} + +/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA", + "#RRGGBB", or "#RRGGBBAA". */ +grub_err_t +grub_video_parse_color (const char *s, grub_video_rgba_color_t *color) +{ + grub_video_rgba_color_t c; + + /* Skip whitespace. */ + while (*s && grub_isspace (*s)) + s++; + + if (*s == '#') + { + /* HTML-style. Number if hex digits: + [6] #RRGGBB [3] #RGB + [8] #RRGGBBAA [4] #RGBA */ + + s++; /* Skip the '#'. */ + /* Count the hexits to determine the format. */ + int hexits = 0; + const char *end = s; + while (my_isxdigit (*end)) + { + end++; + hexits++; + } + + /* Parse the color components based on the format. */ + if (hexits == 3 || hexits == 4) + { + c.red = parse_hex_color_component (s, 0, 1); + c.green = parse_hex_color_component (s, 1, 2); + c.blue = parse_hex_color_component (s, 2, 3); + if (hexits == 4) + c.alpha = parse_hex_color_component (s, 3, 4); + else + c.alpha = 255; + } + else if (hexits == 6 || hexits == 8) + { + c.red = parse_hex_color_component (s, 0, 2); + c.green = parse_hex_color_component (s, 2, 4); + c.blue = parse_hex_color_component (s, 4, 6); + if (hexits == 8) + c.alpha = parse_hex_color_component (s, 6, 8); + else + c.alpha = 255; + } + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid HTML-type color string `%s'", s); + } + else if (grub_isdigit (*s)) + { + /* Comma separated decimal values. */ + c.red = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing 1st comma separator in color `%s'", s); + s++; + c.green = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing 2nd comma separator in color `%s'", s); + s++; + c.blue = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + c.alpha = 255; + else + { + s++; + c.alpha = grub_strtoul (s, 0, 0); + } + } + else + { + if (! grub_video_get_named_color (s, &c)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid named color `%s'", s); + } + + if (grub_errno == GRUB_ERR_NONE) + *color = c; + return grub_errno; +} diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h index c52a3c71c..f858e9d49 100644 --- a/include/grub/gfxmenu_view.h +++ b/include/grub/gfxmenu_view.h @@ -87,11 +87,11 @@ struct grub_gfxmenu_view grub_font_t title_font; grub_font_t message_font; char *terminal_font_name; - grub_gui_color_t title_color; - grub_gui_color_t message_color; - grub_gui_color_t message_bg_color; + grub_video_rgba_color_t title_color; + grub_video_rgba_color_t message_color; + grub_video_rgba_color_t message_bg_color; struct grub_video_bitmap *desktop_image; - grub_gui_color_t desktop_color; + grub_video_rgba_color_t desktop_color; grub_gfxmenu_box_t terminal_box; char *title_text; char *progress_message_text; diff --git a/include/grub/gui.h b/include/grub/gui.h index 6e4a11cbe..ef0795cf7 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -31,16 +31,6 @@ status changes. */ #define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__" -/* A representation of a color. Unlike grub_video_color_t, this - representation is independent of any video mode specifics. */ -typedef struct grub_gui_color -{ - grub_uint8_t red; - grub_uint8_t green; - grub_uint8_t blue; - grub_uint8_t alpha; -} grub_gui_color_t; - typedef struct grub_gui_component *grub_gui_component_t; typedef struct grub_gui_container *grub_gui_container_t; typedef struct grub_gui_list *grub_gui_list_t; @@ -242,23 +232,6 @@ grub_gui_set_viewport (const grub_video_rect_t *r, grub_video_rect_t *old) r->height); } -static __inline grub_gui_color_t -grub_gui_color_rgb (int r, int g, int b) -{ - grub_gui_color_t c; - c.red = r; - c.green = g; - c.blue = b; - c.alpha = 255; - return c; -} - -static __inline grub_video_color_t -grub_gui_map_color (grub_gui_color_t c) -{ - return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); -} - static inline int grub_video_have_common_points (const grub_video_rect_t *a, const grub_video_rect_t *b) diff --git a/include/grub/gui_string_util.h b/include/grub/gui_string_util.h index 1baa2eede..34f9a090d 100644 --- a/include/grub/gui_string_util.h +++ b/include/grub/gui_string_util.h @@ -30,8 +30,4 @@ char *grub_resolve_relative_path (const char *base, const char *path); char *grub_get_dirname (const char *file_path); -int grub_gui_get_named_color (const char *name, grub_gui_color_t *color); - -grub_err_t grub_gui_parse_color (const char *s, grub_gui_color_t *color); - #endif /* GRUB_GUI_STRING_UTIL_HEADER */ diff --git a/include/grub/video.h b/include/grub/video.h index 5350d87eb..97bd85bd1 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -27,6 +27,15 @@ specific coding format. */ typedef grub_uint32_t grub_video_color_t; +/* Video color in hardware independent format. */ +typedef struct grub_video_rgba_color +{ + grub_uint8_t red; + grub_uint8_t green; + grub_uint8_t blue; + grub_uint8_t alpha; +} grub_video_rgba_color_t; + /* This structure is driver specific and should not be accessed directly by outside code. */ struct grub_video_render_target; @@ -428,4 +437,27 @@ grub_video_check_mode_flag (grub_video_mode_type_t flags, grub_video_driver_id_t EXPORT_FUNC (grub_video_get_driver_id) (void); +static __inline grub_video_rgba_color_t +grub_video_rgba_color_rgb (int r, int g, int b) +{ + grub_video_rgba_color_t c; + c.red = r; + c.green = g; + c.blue = b; + c.alpha = 255; + return c; +} + +static __inline grub_video_color_t +grub_video_map_rgba_color (grub_video_rgba_color_t c) +{ + return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); +} + +int EXPORT_FUNC (grub_video_get_named_color) (const char *name, + grub_video_rgba_color_t *color); + +grub_err_t EXPORT_FUNC (grub_video_parse_color) (const char *s, + grub_video_rgba_color_t *color); + #endif /* ! GRUB_VIDEO_HEADER */ From f8e2e451e6e19fa94b9e7cc331104eae9b29135d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 10 Dec 2010 18:34:46 +0100 Subject: [PATCH 044/211] handle UTF16 UDF label --- grub-core/fs/udf.c | 68 ++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 0c5da996e..aaf1565f7 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -789,6 +789,43 @@ fail: return 0; } +static char * +read_string (grub_uint8_t *raw, grub_size_t sz) +{ + grub_uint16_t *utf16; + char *ret; + grub_size_t utf16len = 0; + + if (raw[0] != 8 && raw[0] != 16) + return NULL; + + if (raw[0] == 8) + { + unsigned i; + utf16len = sz - 1; + utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + if (!utf16) + return NULL; + for (i = 0; i < utf16len; i++) + utf16[i] = raw[i + 1]; + } + if (raw[0] == 16) + { + unsigned i; + utf16len = (sz - 1) / 2; + utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + if (!utf16) + return NULL; + for (i = 0; i < utf16len; i++) + utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; + } + ret = grub_malloc (utf16len * 3 + 1); + if (ret) + *grub_utf16_to_utf8 ((grub_uint8_t *) ret, utf16, utf16len) = '\0'; + grub_free (utf16); + return ret; +} + static int grub_udf_iterate_dir (grub_fshelp_node_t dir, int NESTED_FUNC_ATTR @@ -842,10 +879,8 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, else { enum grub_fshelp_filetype type; + char *filename; grub_uint8_t raw[dirent.file_ident_length]; - grub_uint16_t utf16[dirent.file_ident_length - 1]; - grub_uint8_t filename[dirent.file_ident_length * 2]; - grub_size_t utf16len = 0; type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); @@ -856,27 +891,14 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, != dirent.file_ident_length) return 0; - if (raw[0] == 8) - { - unsigned i; - utf16len = dirent.file_ident_length - 1; - for (i = 0; i < utf16len; i++) - utf16[i] = raw[i + 1]; - } - if (raw[0] == 16) - { - unsigned i; - utf16len = (dirent.file_ident_length - 1) / 2; - for (i = 0; i < utf16len; i++) - utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; - } - if (raw[0] == 8 || raw[0] == 16) - { - *grub_utf16_to_utf8 (filename, utf16, utf16len) = '\0'; + filename = read_string (raw, dirent.file_ident_length); - if (hook ((char *) filename, type, child)) - return 1; + if (filename && hook (filename, type, child)) + { + grub_free (filename); + return 1; } + grub_free (filename); } } @@ -1033,7 +1055,7 @@ grub_udf_label (grub_device_t device, char **label) if (data) { - *label = grub_strdup ((char *) &data->lvd.ident[1]); + *label = read_string (data->lvd.ident, sizeof (data->lvd.ident)); grub_free (data); } else From 9c55cbe8e70353e078b884b7c8d86f3e7ccf0ada Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 10 Dec 2010 17:47:38 +0000 Subject: [PATCH 045/211] Add a background_color command. * grub-core/term/gfxterm.c (grub_gfxterm_background_color_cmd): New function. (GRUB_MOD_INIT): Register background_color command. (GRUB_MOD_FINI): Unregister background_color command. --- ChangeLog.parse-color | 7 +++++ grub-core/term/gfxterm.c | 63 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/ChangeLog.parse-color b/ChangeLog.parse-color index 93d696c6c..ccba06d3c 100644 --- a/ChangeLog.parse-color +++ b/ChangeLog.parse-color @@ -32,3 +32,10 @@ (gfxmenu): Remove gfxmenu/named_colors.c. (video_colors) [videomodules]: New module, containing video/colors.c. + + Add a background_color command. + + * grub-core/term/gfxterm.c (grub_gfxterm_background_color_cmd): New + function. + (GRUB_MOD_INIT): Register background_color command. + (GRUB_MOD_FINI): Unregister background_color command. diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 9a10d47b0..93367f2bb 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -1180,6 +1180,62 @@ grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, return grub_errno; } +static grub_err_t +grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + grub_video_rgba_color_t color; + grub_uint8_t *data; + unsigned int i; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand"); + + /* Check that we have video adapter active. */ + if (grub_video_get_info (NULL) != GRUB_ERR_NONE) + return grub_errno; + + if (grub_video_parse_color (args[0], &color) != GRUB_ERR_NONE) + return grub_errno; + + /* Destroy existing background bitmap if loaded. */ + if (bitmap) + { + grub_video_bitmap_destroy (bitmap); + bitmap = 0; + + /* Mark whole screen as dirty. */ + dirty_region_add (0, 0, window.width, window.height); + } + + /* Create a filled bitmap so that we get suitable text blending. */ + grub_video_bitmap_create (&bitmap, window.width, window.height, + GRUB_VIDEO_BLIT_FORMAT_RGB_888); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + data = bitmap->data; + for (i = 0; i < window.height * window.width; i++) + { + *data++ = color.red; + *data++ = color.green; + *data++ = color.blue; + } + + bitmap_width = window.width; + bitmap_height = window.height; + + /* Set the border color. */ + virtual_screen.bg_color_display = grub_video_map_rgba_color (color); + + /* Mark whole screen as dirty. */ + dirty_region_add (0, 0, window.width, window.height); + + /* All was ok. */ + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + static struct grub_term_output grub_video_term = { .name = "gfxterm", @@ -1201,6 +1257,7 @@ static struct grub_term_output grub_video_term = }; static grub_extcmd_t background_image_cmd_handle; +static grub_command_t background_color_cmd_handle; GRUB_MOD_INIT(gfxterm) { @@ -1211,10 +1268,16 @@ GRUB_MOD_INIT(gfxterm) N_("[-m (stretch|normal)] FILE"), N_("Load background image for active terminal."), background_image_cmd_options); + background_color_cmd_handle = + grub_register_command ("background_color", + grub_gfxterm_background_color_cmd, + N_("COLOR"), + N_("Set background color for active terminal.")); } GRUB_MOD_FINI(gfxterm) { + grub_unregister_command (background_color_cmd_handle); grub_unregister_extcmd (background_image_cmd_handle); grub_term_unregister_output (&grub_video_term); } From 591baceb34e93e0ebef73f24f581414472804548 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 06:04:21 +0100 Subject: [PATCH 046/211] UDF symlink support --- grub-core/fs/udf.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index aaf1565f7..48aeca3c8 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -884,6 +884,8 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); + if (child->fe.icbtag.file_type == GRUB_UDF_ICBTAG_TYPE_SYMLINK) + type = GRUB_FSHELP_SYMLINK; if ((grub_udf_read_file (dir, 0, offset, dirent.file_ident_length, @@ -909,6 +911,25 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, return 0; } +static char * +grub_ufs_read_symlink (grub_fshelp_node_t node) +{ + grub_size_t sz = U64 (node->fe.file_size); + grub_uint8_t *raw; + char *ret; + + if (sz < 4) + return NULL; + raw = grub_malloc (sz - 4); + if (!raw) + return NULL; + if (grub_udf_read_file (node, NULL, 4, sz - 4, (char *) raw) < 0) + return NULL; + ret = read_string (raw, sz - 4); + grub_free (raw); + return ret; +} + static grub_err_t grub_udf_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, @@ -972,7 +993,8 @@ grub_udf_dir (grub_device_t device, const char *path, if (grub_fshelp_find_file (path, &rootnode, &foundnode, - grub_udf_iterate_dir, 0, GRUB_FSHELP_DIR)) + grub_udf_iterate_dir, grub_ufs_read_symlink, + GRUB_FSHELP_DIR)) goto fail; grub_udf_iterate_dir (foundnode, iterate); @@ -1006,7 +1028,8 @@ grub_udf_open (struct grub_file *file, const char *name) if (grub_fshelp_find_file (name, &rootnode, &foundnode, - grub_udf_iterate_dir, 0, GRUB_FSHELP_REG)) + grub_udf_iterate_dir, grub_ufs_read_symlink, + GRUB_FSHELP_REG)) goto fail; file->data = foundnode; From 88db5b694a1fe9772fb21afe24d1dadbb6a1254f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 06:23:33 +0100 Subject: [PATCH 047/211] file mtime support for reiserfs --- grub-core/fs/reiserfs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c index e92279554..443d71b6f 100644 --- a/grub-core/fs/reiserfs.c +++ b/grub-core/fs/reiserfs.c @@ -222,6 +222,7 @@ struct grub_fshelp_node grub_uint32_t block_number; /* 0 if node is not found. */ grub_uint16_t block_position; grub_uint64_t next_offset; + grub_int32_t mtime; enum grub_reiserfs_item_type type; /* To know how to read the header. */ struct grub_reiserfs_item_header header; }; @@ -868,6 +869,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, entry_v1_stat.rdev, entry_v1_stat.first_direct_byte); #endif + entry_item->mtime = grub_le_to_cpu32 (entry_v1_stat.mtime); if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK) == S_IFLNK) entry_type = GRUB_FSHELP_SYMLINK; @@ -914,6 +916,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, entry_v2_stat.blocks, entry_v2_stat.first_direct_byte); #endif + entry_item->mtime = grub_le_to_cpu32 (entry_v2_stat.mtime); if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK) == S_IFLNK) entry_type = GRUB_FSHELP_SYMLINK; @@ -1276,6 +1279,8 @@ grub_reiserfs_dir (grub_device_t device, const char *path, struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtimeset = 1; + info.mtime = node->mtime; grub_free (node); return hook (filename, &info); } From ebec6850b9a62caa24cc886bdaf647c5a731f4b2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 07:00:31 +0100 Subject: [PATCH 048/211] HFS filesystem mtime support --- grub-core/fs/hfs.c | 18 ++++++++++++++++++ include/grub/hfs.h | 4 +++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index cef856326..a40171dbd 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -1072,6 +1072,23 @@ grub_hfs_label (grub_device_t device, char **label) return grub_errno; } +static grub_err_t +grub_hfs_mtime (grub_device_t device, grub_int32_t *tm) +{ + struct grub_hfs_data *data; + + data = grub_hfs_mount (device->disk); + + if (data) + *tm = grub_be_to_cpu32 (data->sblock.mtime) - 2082844800; + else + *tm = 0; + + grub_free (data); + return grub_errno; +} + + static grub_err_t grub_hfs_uuid (grub_device_t device, char **uuid) { @@ -1107,6 +1124,7 @@ static struct grub_fs grub_hfs_fs = .close = grub_hfs_close, .label = grub_hfs_label, .uuid = grub_hfs_uuid, + .mtime = grub_hfs_mtime, .next = 0 }; diff --git a/include/grub/hfs.h b/include/grub/hfs.h index d93b9a2c9..bf98610d9 100644 --- a/include/grub/hfs.h +++ b/include/grub/hfs.h @@ -39,7 +39,9 @@ typedef struct grub_hfs_extent grub_hfs_datarecord_t[3]; struct grub_hfs_sblock { grub_uint16_t magic; - grub_uint8_t unused[18]; + grub_uint32_t ctime; + grub_uint32_t mtime; + grub_uint8_t unused[10]; grub_uint32_t blksz; grub_uint8_t unused2[4]; grub_uint16_t first_block; From 58fa13fc7c03fdc605103e9a476267dcc3fe7190 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 07:15:44 +0100 Subject: [PATCH 049/211] HFS mtime support --- grub-core/fs/hfs.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index a40171dbd..e4cc23c17 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -131,6 +131,8 @@ struct grub_hfs_dirrec grub_uint8_t type; grub_uint8_t unused[5]; grub_uint32_t dirid; + grub_uint32_t ctime; + grub_uint32_t mtime; } __attribute__ ((packed)); /* Information about a file. */ @@ -142,7 +144,9 @@ struct grub_hfs_filerec grub_uint32_t fileid; grub_uint8_t unused2[2]; grub_uint32_t size; - grub_uint8_t unused3[44]; + grub_uint8_t unused3[18]; + grub_uint32_t mtime; + grub_uint8_t unused4[22]; /* The first 3 extents of the file. The other extents can be found in the extent overflow file. */ @@ -951,19 +955,29 @@ grub_hfs_dir (grub_device_t device, const char *path, int dir_hook (struct grub_hfs_record *rec) { char fname[32] = { 0 }; - char *filetype = rec->data; + struct grub_hfs_dirrec *drec = rec->data; + struct grub_hfs_filerec *frec = rec->data; struct grub_hfs_catalog_key *ckey = rec->key; struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); grub_strncpy (fname, (char *) (ckey->str), ckey->strlen); - if (*filetype == GRUB_HFS_FILETYPE_DIR - || *filetype == GRUB_HFS_FILETYPE_FILE) + if (drec->type == GRUB_HFS_FILETYPE_DIR) { - info.dir = (*filetype == GRUB_HFS_FILETYPE_DIR); + info.dir = 1; + info.mtimeset = 1; + info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800; return hook (fname, &info); } + if (frec->type == GRUB_HFS_FILETYPE_FILE) + { + info.dir = 0; + info.mtimeset = 1; + info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800; + return hook (fname, &info); + } + return 0; } @@ -1088,7 +1102,6 @@ grub_hfs_mtime (grub_device_t device, grub_int32_t *tm) return grub_errno; } - static grub_err_t grub_hfs_uuid (grub_device_t device, char **uuid) { From 7ac6c4842d57817bd35c74d49668422c9f43ba7a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 14:26:34 +0100 Subject: [PATCH 050/211] JFS mtime support --- grub-core/fs/jfs.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 76ef2e540..9e45f56d2 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -153,6 +153,12 @@ struct grub_jfs_leaf_next_dirent grub_uint16_t namepart[15]; } __attribute__ ((packed)); +struct grub_jfs_time +{ + grub_int32_t sec; + grub_int32_t nanosec; +} __attribute__ ((packed)); + struct grub_jfs_inode { grub_uint32_t stamp; @@ -162,7 +168,10 @@ struct grub_jfs_inode grub_uint64_t size; grub_uint8_t unused2[20]; grub_uint32_t mode; - grub_uint8_t unused3[72]; + struct grub_jfs_time atime; + struct grub_jfs_time ctime; + struct grub_jfs_time mtime; + grub_uint8_t unused3[48]; grub_uint8_t unused4[96]; union @@ -751,6 +760,8 @@ grub_jfs_dir (grub_device_t device, const char *path, info.dir = (grub_le_to_cpu32 (inode.mode) & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR; + info.mtimeset = 1; + info.mtime = grub_le_to_cpu32 (inode.mtime.sec); if (hook (diro->name, &info)) goto fail; } From f5ff296240e8575a35b14fc3ec8ca8263b6161c4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 17:46:16 +0100 Subject: [PATCH 051/211] minix mtime support --- grub-core/fs/minix.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 679e1ec51..e0ca09bd7 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -480,6 +480,13 @@ grub_minix_dir (grub_device_t device, const char *path, grub_minix_read_inode (data, grub_le_to_cpu16 (ino)); info.dir = ((GRUB_MINIX_INODE_MODE (data) & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR); + info.mtimeset = 1; +#ifndef MODE_MINIX2 + info.mtime = grub_le_to_cpu32 (data->inode.ctime); +#else + info.mtime = grub_le_to_cpu32 (data->inode.mtime); +#endif + if (hook (filename, &info) ? 1 : 0) break; From 4aab26313076d3fdb10264cd0b38d9d51741646f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 18:20:45 +0100 Subject: [PATCH 052/211] SquashFS mtime support --- grub-core/fs/squash4.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 95797998a..882f5c959 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -509,6 +509,19 @@ grub_squash_close (grub_file_t file) return GRUB_ERR_NONE; } +static grub_err_t +grub_squash_mtime (grub_device_t dev, grub_int32_t *tm) +{ + struct grub_squash_data *data = 0; + + data = squash_mount (dev->disk); + if (! data) + return grub_errno; + *tm = grub_le_to_cpu32 (data->sb.creation_time); + grub_free (data); + return GRUB_ERR_NONE; +} + static struct grub_fs grub_squash_fs = { .name = "squash4", @@ -516,6 +529,7 @@ static struct grub_fs grub_squash_fs = .open = grub_squash_open, .read = grub_squash_read, .close = grub_squash_close, + .mtime = grub_squash_mtime, #ifdef GRUB_UTIL .reserved_first_sector = 0, #endif From 80113a62583c1c1622a1ed2d7ea73dfe2b72e4ce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 18:21:39 +0100 Subject: [PATCH 053/211] declare AFFS, CPIO, TAR and XFS as non-installable explicitly --- grub-core/fs/affs.c | 3 +++ grub-core/fs/cpio.c | 3 +++ grub-core/fs/xfs.c | 3 +++ 3 files changed, 9 insertions(+) diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 3dc80752d..27e03c0c4 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -535,6 +535,9 @@ static struct grub_fs grub_affs_fs = .read = grub_affs_read, .close = grub_affs_close, .label = grub_affs_label, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif .next = 0 }; diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index 486d8215c..a6c7a1261 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -362,6 +362,9 @@ static struct grub_fs grub_cpio_fs = { .open = grub_cpio_open, .read = grub_cpio_read, .close = grub_cpio_close, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif }; #ifdef MODE_USTAR diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 966bade1b..dbe957470 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -822,6 +822,9 @@ static struct grub_fs grub_xfs_fs = .close = grub_xfs_close, .label = grub_xfs_label, .uuid = grub_xfs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif .next = 0 }; From ea17ec49ae1d5d20b93ad7f1c303aa4d1c0682ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 18:32:08 +0100 Subject: [PATCH 054/211] Extend fields in dirent header --- grub-core/fs/squash4.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 882f5c959..1c522f893 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -106,11 +106,9 @@ struct grub_squash_inode struct grub_squash_dirent_header { /* Actually the value is the number of elements - 1. */ - grub_uint16_t nelems; - grub_uint16_t dummy1; - grub_uint32_t ino_chunk; - grub_uint16_t dummy2[2]; -}; + grub_uint32_t nelems; + grub_uint64_t ino_chunk; +} __attribute__ ((packed)); struct grub_squash_dirent { From 5e96cb4452735c9e2beb82dbfbb03b90ec6c2d1f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 18:41:42 +0100 Subject: [PATCH 055/211] Extend few other fields --- grub-core/fs/squash4.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 1c522f893..0f94ae0a2 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -51,23 +51,23 @@ struct grub_squash_super grub_uint32_t dummy1; grub_uint32_t creation_time; grub_uint32_t dummy2; - grub_uint32_t dummy3[2]; + grub_uint64_t dummy3; grub_uint8_t flags; #define SQUASH_FLAG_UNCOMPRESSED_INODES 1 #define SQUASH_FLAG_UNCOMPRESSED_DATA 2 #define SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS 8 grub_uint8_t dummy4[7]; grub_uint16_t root_ino_offset; - grub_uint16_t root_ino_chunk; - grub_uint32_t dummy5; + grub_uint32_t root_ino_chunk; + grub_uint16_t dummy5; grub_uint64_t total_size; grub_uint64_t exttbloffset; - grub_uint32_t dummy6[2]; + grub_uint64_t dummy6; grub_uint64_t inodeoffset; grub_uint64_t diroffset; grub_uint64_t unk1offset; grub_uint64_t unk2offset; -}; +} __attribute__ ((packed)); /* Chunk-based */ @@ -80,25 +80,25 @@ struct grub_squash_inode union { struct { - grub_uint16_t dummy[2]; + grub_uint32_t dummy; grub_uint32_t chunk; grub_uint32_t fragment; grub_uint32_t offset; grub_uint32_t size; - } file; + } __attribute__ ((packed)) file; struct { - grub_uint16_t dummy1[2]; + grub_uint32_t dummy1; grub_uint32_t chunk; - grub_uint16_t dummy2[2]; + grub_uint32_t dummy2; grub_uint16_t size; - grub_uint16_t offset; - grub_uint16_t dummy3[2]; - } dir; + grub_uint32_t offset; + grub_uint16_t dummy3; + } __attribute__ ((packed)) dir; struct { - grub_uint16_t dummy[4]; + grub_uint64_t dummy; grub_uint32_t namelen; char name[0]; - } symlink; + } __attribute__ ((packed)) symlink; }; } __attribute__ ((packed)); From 81ecffbfc19293dd6b14050c775926d9b5478eb8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 18:42:44 +0100 Subject: [PATCH 056/211] Add missing packed attribute --- grub-core/fs/squash4.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 0f94ae0a2..8e8388628 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -99,7 +99,7 @@ struct grub_squash_inode grub_uint32_t namelen; char name[0]; } __attribute__ ((packed)) symlink; - }; + } __attribute__ ((packed)); } __attribute__ ((packed)); /* Chunk-based. */ @@ -121,13 +121,13 @@ struct grub_squash_dirent /* Actually the value is the length of name - 1. */ grub_uint16_t namelen; char name[0]; -}; +} __attribute__ ((packed)); struct grub_squash_frag_desc { grub_uint64_t offset; grub_uint64_t dummy; -}; +} __attribute__ ((packed)); #define SQUASH_CHUNK_SIZE 0x2000 #define SQUASH_CHUNK_FLAGS 0x8000 From 9959c6a70b7bd4d5cccad712a747f90f33f85fa9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 21:15:25 +0100 Subject: [PATCH 057/211] Fix AFFS rootblock detection --- grub-core/fs/affs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 27e03c0c4..40be4b2f6 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -208,7 +208,7 @@ grub_affs_mount (grub_disk_t disk) rblock = (struct grub_affs_rblock *) rootblock; /* Read the rootblock. */ - grub_disk_read (disk, (disk->total_sectors >> 1) + blocksize, 0, + grub_disk_read (disk, grub_be_to_cpu32 (data->bblock.rootblock), 0, GRUB_DISK_SECTOR_SIZE * 16, rootblock); if (grub_errno) goto fail; @@ -240,7 +240,7 @@ grub_affs_mount (grub_disk_t disk) data->disk = disk; data->htsize = grub_be_to_cpu32 (rblock->htsize); data->diropen.data = data; - data->diropen.block = (disk->total_sectors >> 1); + data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock); grub_free (rootblock); @@ -507,7 +507,7 @@ grub_affs_label (grub_device_t device, char **label) { /* The rootblock maps quite well on a file header block, it's something we can use here. */ - grub_disk_read (data->disk, disk->total_sectors >> 1, + grub_disk_read (data->disk, grub_be_to_cpu32 (data->bblock.rootblock), data->blocksize * (GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION), sizeof (file), &file); From e21c35641397325aa9411b41239e4779212ebe0e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 21:59:22 +0100 Subject: [PATCH 058/211] restructure AFFS fshelp_node-related code --- grub-core/fs/affs.c | 84 ++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 40be4b2f6..343af6681 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -50,12 +50,20 @@ struct grub_affs_rblock grub_uint32_t hashtable[1]; } __attribute__ ((packed)); +struct grub_affs_time +{ + grub_int32_t day; + grub_uint32_t min; + grub_uint32_t fractions_of_sec; +} __attribute__ ((packed)); + /* The second part of a file header block. */ struct grub_affs_file { grub_uint8_t unused1[12]; grub_uint32_t size; - grub_uint8_t unused2[104]; + grub_uint8_t unused2[92]; + struct grub_affs_time mtime; grub_uint8_t namelen; grub_uint8_t name[30]; grub_uint8_t unused3[33]; @@ -85,9 +93,9 @@ struct grub_affs_file struct grub_fshelp_node { struct grub_affs_data *data; - int block; - int size; - int parent; + grub_disk_addr_t block; + struct grub_fshelp_node *parent; + struct grub_affs_file di; }; /* Information about a "mounted" affs filesystem. */ @@ -154,7 +162,7 @@ grub_affs_read_file (grub_fshelp_node_t node, { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_affs_read_block, - node->size, 0); + grub_be_to_cpu32 (node->di.size), 0); } @@ -241,6 +249,8 @@ grub_affs_mount (grub_disk_t disk) data->htsize = grub_be_to_cpu32 (rblock->htsize); data->diropen.data = data; data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock); + data->diropen.parent = NULL; + grub_memcpy (&data->diropen.di, rootblock, sizeof (data->diropen.di)); grub_free (rootblock); @@ -291,12 +301,15 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, struct grub_affs_data *data = dir->data; grub_uint32_t *hashtable; - auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block, - int size, int type); + auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, + grub_disk_addr_t block, + const struct grub_affs_file *fil); - int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block, - int size, int type) + int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, + grub_disk_addr_t block, + const struct grub_affs_file *fil) { + int type; node = grub_malloc (sizeof (*node)); if (!node) { @@ -304,10 +317,19 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, return 1; } + if ((int) grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_DIR) + type = GRUB_FSHELP_REG; + else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_REG) + type = GRUB_FSHELP_DIR; + else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else + type = GRUB_FSHELP_UNKNOWN; + node->data = data; - node->size = size; node->block = block; - node->parent = grub_be_to_cpu32 (file.parent); + node->di = *fil; + node->parent = dir; if (hook (name, type, node)) { @@ -317,6 +339,24 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, return 0; } + /* Create the directory entries for `.' and `..'. */ + node = grub_malloc (sizeof (*node)); + if (!node) + return 1; + + *node = *dir; + if (hook (".", GRUB_FSHELP_DIR, node)) + return 1; + if (dir->parent) + { + node = grub_malloc (sizeof (*node)); + if (!node) + return 1; + *node = *dir->parent; + if (hook ("..", GRUB_FSHELP_DIR, node)) + return 1; + } + hashtable = grub_malloc (data->htsize * sizeof (*hashtable)); if (!hashtable) return 1; @@ -326,16 +366,8 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, if (grub_errno) goto fail; - /* Create the directory entries for `.' and `..'. */ - if (grub_affs_create_node (".", dir->block, dir->size, GRUB_FSHELP_DIR)) - return 1; - if (grub_affs_create_node ("..", dir->parent ? dir->parent : dir->block, - dir->size, GRUB_FSHELP_DIR)) - return 1; - for (i = 0; i < data->htsize; i++) { - enum grub_fshelp_filetype type; grub_uint64_t next; if (!hashtable[i]) @@ -356,17 +388,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, file.name[file.namelen] = '\0'; - if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR) - type = GRUB_FSHELP_REG; - else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_REG) - type = GRUB_FSHELP_DIR; - else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_SYMLINK) - type = GRUB_FSHELP_SYMLINK; - else - type = GRUB_FSHELP_UNKNOWN; - - if (grub_affs_create_node ((char *) (file.name), next, - grub_be_to_cpu32 (file.size), type)) + if (grub_affs_create_node ((char *) (file.name), next, &file)) return 1; next = grub_be_to_cpu32 (file.next); @@ -401,7 +423,7 @@ grub_affs_open (struct grub_file *file, const char *name) if (grub_errno) goto fail; - file->size = fdiro->size; + file->size = grub_be_to_cpu32 (fdiro->di.size); data->diropen = *fdiro; grub_free (fdiro); From 790aaa8c9f63a151c3cf45ea5d907c10174a2940 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 22:02:22 +0100 Subject: [PATCH 059/211] AFFS mtime support --- grub-core/fs/affs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 343af6681..e4b487a7e 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -54,7 +54,7 @@ struct grub_affs_time { grub_int32_t day; grub_uint32_t min; - grub_uint32_t fractions_of_sec; + grub_uint32_t hz; } __attribute__ ((packed)); /* The second part of a file header block. */ @@ -487,6 +487,11 @@ grub_affs_dir (grub_device_t device, const char *path, struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtimeset = 1; + info.mtime = grub_be_to_cpu32 (node->di.mtime.day) * 86400 + + grub_be_to_cpu32 (node->di.mtime.min) * 60 + + grub_be_to_cpu32 (node->di.mtime.hz) / 50 + + 8 * 365 * 86400 + 86400 * 2; grub_free (node); return hook (filename, &info); } From bd1de4341b4bc6cc1e616674a3fc1ff1c12120fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 22:33:34 +0100 Subject: [PATCH 060/211] explicitly declare SFS as not installable --- grub-core/fs/sfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c index 4a5005908..b49420de1 100644 --- a/grub-core/fs/sfs.c +++ b/grub-core/fs/sfs.c @@ -579,6 +579,9 @@ static struct grub_fs grub_sfs_fs = .read = grub_sfs_read, .close = grub_sfs_close, .label = grub_sfs_label, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif .next = 0 }; From 7b32d83d7834b4f36fbbbff7c526a07f1879c5b0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 22:48:29 +0100 Subject: [PATCH 061/211] SFS mtime support --- grub-core/fs/sfs.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c index b49420de1..dc4fbd45c 100644 --- a/grub-core/fs/sfs.c +++ b/grub-core/fs/sfs.c @@ -66,7 +66,7 @@ struct grub_sfs_obj grub_uint32_t dir_objc; } dir __attribute__ ((packed)); } file_dir; - grub_uint8_t unused3[4]; + grub_uint32_t mtime; grub_uint8_t type; grub_uint8_t filename[1]; grub_uint8_t comment[1]; @@ -119,6 +119,7 @@ struct grub_fshelp_node struct grub_sfs_data *data; int block; int size; + grub_uint32_t mtime; }; /* Information about a "mounted" sfs filesystem. */ @@ -355,10 +356,12 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir, int pos; auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block, - int size, int type); + int size, int type, + grub_uint32_t mtime); int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block, - int size, int type) + int size, int type, + grub_uint32_t mtime) { node = grub_malloc (sizeof (*node)); if (!node) @@ -367,6 +370,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir, node->data = data; node->size = size; node->block = block; + node->mtime = mtime; return hook (name, type, node); } @@ -426,7 +430,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir, if (grub_sfs_create_node (filename, block, grub_be_to_cpu32 (obj->file_dir.file.size), - type)) + type, grub_be_to_cpu32 (obj->mtime))) { grub_free (objc_data); return 1; @@ -525,6 +529,8 @@ grub_sfs_dir (grub_device_t device, const char *path, struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtime = node->mtime + 8 * 365 * 86400 + 86400 * 2; + info.mtimeset = 1; grub_free (node); return hook (filename, &info); } From 0e5507c411c63bdbddd2fcf1c6628a8ec29c87a4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Dec 2010 01:00:33 +0100 Subject: [PATCH 062/211] mtime support for ntfs --- grub-core/fs/ntfs.c | 8 ++++++++ include/grub/ntfs.h | 1 + 2 files changed, 9 insertions(+) diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 414f6513d..7a5e2b158 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -610,6 +610,10 @@ list_file (struct grub_ntfs_file *diro, char *pos, fdiro->data = diro->data; fdiro->ino = u32at (pos, 0); + if (u64at (pos, 0x20) > u64at (pos, 0x28)) + fdiro->mtime = u64at (pos, 0x20); + else + fdiro->mtime = u64at (pos, 0x28); ustr = grub_malloc (ns * 4 + 1); if (ustr == NULL) @@ -880,6 +884,10 @@ grub_ntfs_dir (grub_device_t device, const char *path, struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtimeset = 1; + info.mtime = grub_divmod64 (node->mtime, 10000000, 0) + - 86400ULL * 365 * (1970 - 1601) + - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100); grub_free (node); return hook (filename, &info); } diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h index 31b99398b..0a089b3c0 100644 --- a/include/grub/ntfs.h +++ b/include/grub/ntfs.h @@ -135,6 +135,7 @@ struct grub_fshelp_node struct grub_ntfs_data *data; char *buf; grub_uint64_t size; + grub_uint64_t mtime; grub_uint32_t ino; int inode_read; struct grub_ntfs_attr attr; From 198cae0c965abe97370b13d67e777f1136d4a1c2 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Dec 2010 13:58:53 +0000 Subject: [PATCH 063/211] Fix border repainting. * grub-core/term/gfxterm.c (dirty_region_add): When a repaint is already scheduled, merge the virtual screen with the requested region rather than repainting only the virtual screen. --- ChangeLog.parse-color | 6 ++++++ grub-core/term/gfxterm.c | 18 ++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/ChangeLog.parse-color b/ChangeLog.parse-color index ccba06d3c..941cd5aad 100644 --- a/ChangeLog.parse-color +++ b/ChangeLog.parse-color @@ -39,3 +39,9 @@ function. (GRUB_MOD_INIT): Register background_color command. (GRUB_MOD_FINI): Unregister background_color command. + + Fix border repainting. + + * grub-core/term/gfxterm.c (dirty_region_add): When a repaint is + already scheduled, merge the virtual screen with the requested + region rather than repainting only the virtual screen. diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 93367f2bb..c914f8d2c 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -539,10 +539,20 @@ dirty_region_add (int x, int y, unsigned int width, unsigned int height) if (repaint_scheduled) { - x = virtual_screen.offset_x; - y = virtual_screen.offset_y; - width = virtual_screen.width; - height = virtual_screen.height; + if (x > (int)virtual_screen.offset_x) + { + width += virtual_screen.offset_x - x; + x = virtual_screen.offset_x; + } + if (y > (int)virtual_screen.offset_y) + { + height += virtual_screen.offset_y - y; + y = virtual_screen.offset_y; + } + if (width < virtual_screen.width) + width = virtual_screen.width; + if (height < virtual_screen.height) + height = virtual_screen.height; repaint_scheduled = 0; repaint_was_scheduled = 1; } From 159b4a8bb76f98d294fac139b4f3f4e21c03a03e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 14 Dec 2010 12:28:36 +0000 Subject: [PATCH 064/211] (redraw_screen_rect): Allow blend/replace of text layer to be controlled independently from whether there is a background bitmap. (grub_gfxterm_fullscreen): Change blend_text_bg when changing bitmap. (destroy_window): Likewise. (grub_gfxterm_background_image_cmd): Likewise. --- ChangeLog.parse-color | 6 +++++ grub-core/term/gfxterm.c | 55 ++++++++++++++++------------------------ 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/ChangeLog.parse-color b/ChangeLog.parse-color index 941cd5aad..b241f3b73 100644 --- a/ChangeLog.parse-color +++ b/ChangeLog.parse-color @@ -39,6 +39,12 @@ function. (GRUB_MOD_INIT): Register background_color command. (GRUB_MOD_FINI): Unregister background_color command. + (redraw_screen_rect): Allow blend/replace of text layer to be + controlled independently from whether there is a background bitmap. + (grub_gfxterm_fullscreen): Change blend_text_bg when changing + bitmap. + (destroy_window): Likewise. + (grub_gfxterm_background_image_cmd): Likewise. Fix border repainting. diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index c914f8d2c..108ce941a 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -128,6 +128,7 @@ static struct grub_video_render_target *text_layer; static unsigned int bitmap_width; static unsigned int bitmap_height; static struct grub_video_bitmap *bitmap; +static int blend_text_bg; static struct grub_dirty_region dirty_region; @@ -344,6 +345,7 @@ grub_gfxterm_fullscreen (void) grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); } bitmap = 0; + blend_text_bg = 0; /* Select the font to use. */ font_name = grub_env_get ("gfxterm_font"); @@ -396,6 +398,7 @@ destroy_window (void) { grub_video_bitmap_destroy (bitmap); bitmap = 0; + blend_text_bg = 0; } repaint_callback = 0; @@ -481,26 +484,27 @@ redraw_screen_rect (unsigned int x, unsigned int y, /* Render background layer. */ grub_video_fill_rect (color, x, ty, width, h); } - - /* Render text layer as blended. */ - grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, x, y, - x - virtual_screen.offset_x, - y - virtual_screen.offset_y, - width, height); } else { /* Render background layer. */ color = virtual_screen.bg_color_display; grub_video_fill_rect (color, x, y, width, height); - - /* Render text layer as replaced (to get texts background color). */ - grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_REPLACE, x, y, - x - virtual_screen.offset_x, - y - virtual_screen.offset_y, - width, height); } + if (blend_text_bg) + /* Render text layer as blended. */ + grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, x, y, + x - virtual_screen.offset_x, + y - virtual_screen.offset_y, + width, height); + else + /* Render text layer as replaced (to get texts background color). */ + grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_REPLACE, x, y, + x - virtual_screen.offset_x, + y - virtual_screen.offset_y, + width, height); + /* Restore saved viewport. */ grub_video_set_viewport (saved_view.x, saved_view.y, saved_view.width, saved_view.height); @@ -1137,6 +1141,7 @@ grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, { grub_video_bitmap_destroy (bitmap); bitmap = 0; + blend_text_bg = 0; /* Mark whole screen as dirty. */ dirty_region_add (0, 0, window.width, window.height); @@ -1169,6 +1174,7 @@ grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, /* Replace the original bitmap with the scaled one. */ grub_video_bitmap_destroy (bitmap); bitmap = scaled_bitmap; + blend_text_bg = 1; } } } @@ -1195,8 +1201,6 @@ grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_video_rgba_color_t color; - grub_uint8_t *data; - unsigned int i; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand"); @@ -1218,25 +1222,10 @@ grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), dirty_region_add (0, 0, window.width, window.height); } - /* Create a filled bitmap so that we get suitable text blending. */ - grub_video_bitmap_create (&bitmap, window.width, window.height, - GRUB_VIDEO_BLIT_FORMAT_RGB_888); - if (grub_errno != GRUB_ERR_NONE) - return grub_errno; - - data = bitmap->data; - for (i = 0; i < window.height * window.width; i++) - { - *data++ = color.red; - *data++ = color.green; - *data++ = color.blue; - } - - bitmap_width = window.width; - bitmap_height = window.height; - - /* Set the border color. */ - virtual_screen.bg_color_display = grub_video_map_rgba_color (color); + /* Set the background and border colors. */ + virtual_screen.bg_color = grub_video_map_rgba_color (color); + virtual_screen.bg_color_display = virtual_screen.bg_color; + blend_text_bg = 1; /* Mark whole screen as dirty. */ dirty_region_add (0, 0, window.width, window.height); From 477343c86e0b1e4279be40a1af488e7755f20339 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 15 Dec 2010 01:31:07 +0000 Subject: [PATCH 065/211] make sure virtual_screen.bg_color is compatible with the text layer --- grub-core/term/gfxterm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 108ce941a..09363918a 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -1201,6 +1201,7 @@ grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_video_rgba_color_t color; + struct grub_video_render_target *old_target; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand"); @@ -1222,9 +1223,13 @@ grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), dirty_region_add (0, 0, window.width, window.height); } - /* Set the background and border colors. */ + /* Set the background and border colors. The background color needs to be + compatible with the text layer. */ + grub_video_get_active_render_target (&old_target); + grub_video_set_active_render_target (text_layer); virtual_screen.bg_color = grub_video_map_rgba_color (color); - virtual_screen.bg_color_display = virtual_screen.bg_color; + grub_video_set_active_render_target (old_target); + virtual_screen.bg_color_display = grub_video_map_rgba_color (color); blend_text_bg = 1; /* Mark whole screen as dirty. */ From 29184e9312b4302932720e1bcdd478eaa2999b7e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Dec 2010 19:49:35 +0100 Subject: [PATCH 066/211] romfs support --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/romfs.c | 345 ++++++++++++++++++++++++++++++++++++ 3 files changed, 351 insertions(+) create mode 100644 grub-core/fs/romfs.c diff --git a/Makefile.util.def b/Makefile.util.def index 74984e2e9..6279f510a 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -64,6 +64,7 @@ library = { common = grub-core/fs/ntfs.c; common = grub-core/fs/ntfscomp.c; common = grub-core/fs/reiserfs.c; + common = grub-core/fs/romfs.c; common = grub-core/fs/sfs.c; common = grub-core/fs/tar.c; common = grub-core/fs/udf.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 37c0ce970..f5bbb888d 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -977,6 +977,11 @@ module = { common = fs/reiserfs.c; }; +module = { + name = romfs; + common = fs/romfs.c; +}; + module = { name = sfs; common = fs/sfs.c; diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c new file mode 100644 index 000000000..ad0b6a4c4 --- /dev/null +++ b/grub-core/fs/romfs.c @@ -0,0 +1,345 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +struct grub_romfs_superblock +{ + char magic[8]; +#define GRUB_ROMFS_MAGIC "-rom1fs-" + grub_uint32_t total_size; + grub_uint32_t chksum; + char label[0]; +}; + +struct grub_romfs_file_header +{ + grub_uint32_t next_file; + grub_uint32_t spec; + grub_uint32_t size; + grub_uint32_t chksum; + char name[0]; +}; + +struct grub_romfs_data +{ + grub_disk_addr_t first_file; + grub_disk_t disk; +}; + +struct grub_fshelp_node +{ + grub_disk_addr_t addr; + struct grub_romfs_data *data; + /* Used only on regular files. */ + grub_disk_addr_t data_addr; + struct grub_romfs_file_header file; +}; + +#define GRUB_ROMFS_ALIGN 16 +#define GRUB_ROMFS_TYPE_MASK 7 +#define GRUB_ROMFS_TYPE_REGULAR 2 +#define GRUB_ROMFS_TYPE_DIRECTORY 1 + +static grub_err_t +do_checksum (void *in, grub_size_t insize) +{ + grub_uint32_t *a = in; + grub_size_t sz = insize / 4; + grub_uint32_t *b = a + sz; + grub_uint32_t csum = 0; + + while (a < b) + csum += grub_be_to_cpu32 (*a++); + if (csum) + return grub_error (GRUB_ERR_BAD_FS, "invalid checksum"); + return GRUB_ERR_NONE; +} + +static struct grub_romfs_data * +grub_romfs_mount (grub_device_t dev) +{ + union { + struct grub_romfs_superblock sb; + char d[512]; + } sb; + grub_err_t err; + char *ptr; + grub_disk_addr_t sec = 0; + struct grub_romfs_data *data; + if (!dev->disk) + { + grub_error (GRUB_ERR_BAD_FS, "not a disk"); + return NULL; + } + err = grub_disk_read (dev->disk, 0, 0, sizeof (sb), &sb); + if (err == GRUB_ERR_OUT_OF_RANGE) + err = grub_errno = GRUB_ERR_BAD_FS; + if (err) + return NULL; + if (grub_be_to_cpu32 (sb.sb.total_size) < sizeof (sb)) + { + grub_error (GRUB_ERR_BAD_FS, "too short filesystem"); + return NULL; + } + err = do_checksum (&sb, sizeof (sb) < grub_be_to_cpu32 (sb.sb.total_size) ? + sizeof (sb) : grub_be_to_cpu32 (sb.sb.total_size)); + if (err) + return NULL; + for (ptr = sb.sb.label; (void *) ptr < (void *) (&sb + 1) + && ptr < sb.d + grub_be_to_cpu32 (sb.sb.total_size); ptr++) + if (!*ptr) + break; + if ((void *) ptr == &sb + 1) + for (sec++; ; sec++) + { + err = grub_disk_read (dev->disk, sec, 0, sizeof (sb), &sb); + if (err == GRUB_ERR_OUT_OF_RANGE) + err = grub_errno = GRUB_ERR_BAD_FS; + if (err) + return NULL; + for (ptr = sb.d; (void *) ptr < (void *) (&sb + 1) + && ptr < sb.d + grub_be_to_cpu32 (sb.sb.total_size); ptr++) + if (!*ptr) + break; + } + data = grub_malloc (sizeof (*data)); + if (!data) + return NULL; + data->first_file = ALIGN_UP (ptr - sb.d, GRUB_ROMFS_ALIGN) + sec * 512; + data->disk = dev->disk; + return data; +} + +static int +grub_romfs_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + grub_disk_addr_t caddr; + struct grub_romfs_file_header hdr; + grub_size_t a = 0; + char *name = NULL; + unsigned nptr; + unsigned i, j; + for (caddr = dir->addr; caddr; + caddr = grub_be_to_cpu32 (hdr.next_file) & ~(GRUB_ROMFS_ALIGN - 1)) + { + grub_disk_addr_t naddr = caddr + sizeof (hdr); + grub_uint32_t csum = 0; + enum grub_fshelp_filetype filetype = GRUB_FSHELP_UNKNOWN; + struct grub_fshelp_node *node; + grub_err_t err; + + err = grub_disk_read (dir->data->disk, caddr >> GRUB_DISK_SECTOR_BITS, + caddr & (GRUB_DISK_SECTOR_SIZE - 1), + sizeof (hdr), &hdr); + if (err) + { + grub_free (name); + return 1; + } + for (nptr = 0; ; nptr++, naddr += 16) + { + if (a >= nptr) + { + char *on; + a = 2 * (nptr + 1); + on = name; + name = grub_realloc (name, a * 16); + if (!name) + { + grub_free (on); + return 1; + } + } + err = grub_disk_read (dir->data->disk, naddr >> GRUB_DISK_SECTOR_BITS, + naddr & (GRUB_DISK_SECTOR_SIZE - 1), + 16, name + 16 * nptr); + if (err) + return err; + for (j = 0; j < 16; j++) + if (!name[16 * nptr + j]) + break; + if (j != 16) + break; + } + for (i = 0; i < sizeof (hdr) / sizeof (grub_uint32_t); i++) + csum += grub_be_to_cpu32 (((grub_uint32_t *) &hdr)[i]); + for (i = 0; i < (nptr + 1) * 4; i++) + csum += grub_be_to_cpu32 (((grub_uint32_t *) name)[i]); + if (csum != 0) + { + grub_error (GRUB_ERR_BAD_FS, "invalid checksum"); + grub_free (name); + return 1; + } + node = grub_malloc (sizeof (*node)); + if (!node) + return 1; + node->addr = caddr; + node->data_addr = caddr + (nptr + 1) * 16 + sizeof (hdr); + node->data = dir->data; + node->file = hdr; + switch (grub_be_to_cpu32 (hdr.next_file) & GRUB_ROMFS_TYPE_MASK) + { + case GRUB_ROMFS_TYPE_REGULAR: + filetype = GRUB_FSHELP_REG; + break; + case GRUB_ROMFS_TYPE_DIRECTORY: + filetype = GRUB_FSHELP_DIR; + break; + } + + if (hook (name, filetype, node)) + { + grub_free (name); + return 1; + } + } + grub_free (name); + return 0; +} + +static grub_err_t +grub_romfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)) +{ + struct grub_romfs_data *data = 0; + struct grub_fshelp_node *fdiro = 0, start; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, &info); + } + + data = grub_romfs_mount (device); + if (! data) + goto fail; + + start.addr = data->first_file; + start.data = data; + grub_fshelp_find_file (path, &start, &fdiro, grub_romfs_iterate_dir, + NULL, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_romfs_iterate_dir (fdiro, iterate); + + fail: + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_romfs_open (struct grub_file *file, const char *name) +{ + struct grub_romfs_data *data = 0; + struct grub_fshelp_node *fdiro = 0, start; + + data = grub_romfs_mount (file->device); + if (! data) + goto fail; + + start.addr = data->first_file; + start.data = data; + + grub_fshelp_find_file (name, &start, &fdiro, grub_romfs_iterate_dir, + NULL, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + file->size = grub_be_to_cpu32 (fdiro->file.size); + file->data = fdiro; + + fail: + grub_free (data); + + return grub_errno; +} + +static grub_ssize_t +grub_romfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_fshelp_node *data = file->data; + + /* XXX: The file is stored in as a single extent. */ + data->data->disk->read_hook = file->read_hook; + grub_disk_read (data->data->disk, + (data->data_addr + file->offset) >> GRUB_DISK_SECTOR_BITS, + (data->data_addr + file->offset) & (GRUB_DISK_SECTOR_SIZE - 1), + len, buf); + data->data->disk->read_hook = NULL; + + if (grub_errno) + return -1; + + return len; +} + +static grub_err_t +grub_romfs_close (grub_file_t file) +{ + grub_free (file->data); + + return GRUB_ERR_NONE; +} + +static struct grub_fs grub_romfs_fs = + { + .name = "romfs", + .dir = grub_romfs_dir, + .open = grub_romfs_open, + .read = grub_romfs_read, + .close = grub_romfs_close, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif + .next = 0 + }; + +GRUB_MOD_INIT(romfs) +{ + grub_fs_register (&grub_romfs_fs); +} + +GRUB_MOD_FINI(romfs) +{ + grub_fs_unregister (&grub_romfs_fs); +} From 921c7932d0ce8ff5bc36570a02fc220f9887139c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Dec 2010 20:24:16 +0100 Subject: [PATCH 067/211] directory and hardlink support on romfs --- grub-core/fs/romfs.c | 54 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index ad0b6a4c4..a642615c3 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -52,15 +52,16 @@ struct grub_fshelp_node { grub_disk_addr_t addr; struct grub_romfs_data *data; - /* Used only on regular files. */ grub_disk_addr_t data_addr; + /* Not filled for root. */ struct grub_romfs_file_header file; }; #define GRUB_ROMFS_ALIGN 16 #define GRUB_ROMFS_TYPE_MASK 7 -#define GRUB_ROMFS_TYPE_REGULAR 2 +#define GRUB_ROMFS_TYPE_HARDLINK 0 #define GRUB_ROMFS_TYPE_DIRECTORY 1 +#define GRUB_ROMFS_TYPE_REGULAR 2 static grub_err_t do_checksum (void *in, grub_size_t insize) @@ -145,7 +146,7 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, char *name = NULL; unsigned nptr; unsigned i, j; - for (caddr = dir->addr; caddr; + for (caddr = dir->data_addr; caddr; caddr = grub_be_to_cpu32 (hdr.next_file) & ~(GRUB_ROMFS_ALIGN - 1)) { grub_disk_addr_t naddr = caddr + sizeof (hdr); @@ -180,7 +181,7 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, naddr & (GRUB_DISK_SECTOR_SIZE - 1), 16, name + 16 * nptr); if (err) - return err; + return 1; for (j = 0; j < 16; j++) if (!name[16 * nptr + j]) break; @@ -210,8 +211,51 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, filetype = GRUB_FSHELP_REG; break; case GRUB_ROMFS_TYPE_DIRECTORY: + node->data_addr = grub_be_to_cpu32 (hdr.spec); filetype = GRUB_FSHELP_DIR; break; + case GRUB_ROMFS_TYPE_HARDLINK: + { + grub_disk_addr_t laddr; + node->addr = laddr = grub_be_to_cpu32 (hdr.spec); + err = grub_disk_read (dir->data->disk, + laddr >> GRUB_DISK_SECTOR_BITS, + laddr & (GRUB_DISK_SECTOR_SIZE - 1), + sizeof (node->file), &node->file); + if (err) + return 1; + if ((grub_be_to_cpu32 (node->file.next_file) & GRUB_ROMFS_TYPE_MASK) + == GRUB_ROMFS_TYPE_REGULAR) + { + laddr += sizeof (hdr); + while (1) + { + char buf[16]; + err = grub_disk_read (dir->data->disk, + laddr >> GRUB_DISK_SECTOR_BITS, + laddr & (GRUB_DISK_SECTOR_SIZE - 1), + 16, buf); + if (err) + return 1; + for (i = 0; i < 16; i++) + if (!buf[i]) + break; + if (i != 16) + break; + laddr += 16; + } + node->data_addr = laddr + 16; + filetype = GRUB_FSHELP_REG; + } + if ((grub_be_to_cpu32 (node->file.next_file) & GRUB_ROMFS_TYPE_MASK) + == GRUB_ROMFS_TYPE_DIRECTORY) + { + node->data_addr = grub_be_to_cpu32 (node->file.spec); + filetype = GRUB_FSHELP_DIR; + } + + break; + } } if (hook (name, filetype, node)) @@ -253,6 +297,7 @@ grub_romfs_dir (grub_device_t device, const char *path, goto fail; start.addr = data->first_file; + start.data_addr = data->first_file; start.data = data; grub_fshelp_find_file (path, &start, &fdiro, grub_romfs_iterate_dir, NULL, GRUB_FSHELP_DIR); @@ -278,6 +323,7 @@ grub_romfs_open (struct grub_file *file, const char *name) goto fail; start.addr = data->first_file; + start.data_addr = data->first_file; start.data = data; grub_fshelp_find_file (name, &start, &fdiro, grub_romfs_iterate_dir, From 20af85758134eb05ecdb950ce113a3145530842d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Dec 2010 20:36:54 +0100 Subject: [PATCH 068/211] symlink support on romfs --- grub-core/fs/romfs.c | 56 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index a642615c3..342bdd733 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -62,6 +62,7 @@ struct grub_fshelp_node #define GRUB_ROMFS_TYPE_HARDLINK 0 #define GRUB_ROMFS_TYPE_DIRECTORY 1 #define GRUB_ROMFS_TYPE_REGULAR 2 +#define GRUB_ROMFS_TYPE_SYMLINK 3 static grub_err_t do_checksum (void *in, grub_size_t insize) @@ -133,6 +134,27 @@ grub_romfs_mount (grub_device_t dev) return data; } +static char * +grub_romfs_read_symlink (grub_fshelp_node_t node) +{ + char *ret; + grub_err_t err; + ret = grub_malloc (grub_be_to_cpu32 (node->file.size) + 1); + if (!ret) + return NULL; + err = grub_disk_read (node->data->disk, + (node->data_addr) >> GRUB_DISK_SECTOR_BITS, + (node->data_addr) & (GRUB_DISK_SECTOR_SIZE - 1), + grub_be_to_cpu32 (node->file.size), ret); + if (err) + { + grub_free (ret); + return NULL; + } + ret[grub_be_to_cpu32 (node->file.size)] = 0; + return ret; +} + static int grub_romfs_iterate_dir (grub_fshelp_node_t dir, int NESTED_FUNC_ATTR @@ -210,6 +232,9 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, case GRUB_ROMFS_TYPE_REGULAR: filetype = GRUB_FSHELP_REG; break; + case GRUB_ROMFS_TYPE_SYMLINK: + filetype = GRUB_FSHELP_SYMLINK; + break; case GRUB_ROMFS_TYPE_DIRECTORY: node->data_addr = grub_be_to_cpu32 (hdr.spec); filetype = GRUB_FSHELP_DIR; @@ -225,7 +250,9 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, if (err) return 1; if ((grub_be_to_cpu32 (node->file.next_file) & GRUB_ROMFS_TYPE_MASK) - == GRUB_ROMFS_TYPE_REGULAR) + == GRUB_ROMFS_TYPE_REGULAR + || (grub_be_to_cpu32 (node->file.next_file) + & GRUB_ROMFS_TYPE_MASK) == GRUB_ROMFS_TYPE_SYMLINK) { laddr += sizeof (hdr); while (1) @@ -245,16 +272,21 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, laddr += 16; } node->data_addr = laddr + 16; - filetype = GRUB_FSHELP_REG; } - if ((grub_be_to_cpu32 (node->file.next_file) & GRUB_ROMFS_TYPE_MASK) - == GRUB_ROMFS_TYPE_DIRECTORY) - { - node->data_addr = grub_be_to_cpu32 (node->file.spec); - filetype = GRUB_FSHELP_DIR; - } - - break; + if ((grub_be_to_cpu32 (node->file.next_file) + & GRUB_ROMFS_TYPE_MASK) == GRUB_ROMFS_TYPE_REGULAR) + filetype = GRUB_FSHELP_REG; + if ((grub_be_to_cpu32 (node->file.next_file) + & GRUB_ROMFS_TYPE_MASK) == GRUB_ROMFS_TYPE_SYMLINK) + filetype = GRUB_FSHELP_SYMLINK; + if ((grub_be_to_cpu32 (node->file.next_file) & GRUB_ROMFS_TYPE_MASK) + == GRUB_ROMFS_TYPE_DIRECTORY) + { + node->data_addr = grub_be_to_cpu32 (node->file.spec); + filetype = GRUB_FSHELP_DIR; + } + + break; } } @@ -300,7 +332,7 @@ grub_romfs_dir (grub_device_t device, const char *path, start.data_addr = data->first_file; start.data = data; grub_fshelp_find_file (path, &start, &fdiro, grub_romfs_iterate_dir, - NULL, GRUB_FSHELP_DIR); + grub_romfs_read_symlink, GRUB_FSHELP_DIR); if (grub_errno) goto fail; @@ -327,7 +359,7 @@ grub_romfs_open (struct grub_file *file, const char *name) start.data = data; grub_fshelp_find_file (name, &start, &fdiro, grub_romfs_iterate_dir, - NULL, GRUB_FSHELP_REG); + grub_romfs_read_symlink, GRUB_FSHELP_REG); if (grub_errno) goto fail; From 44932541564c681250d819fe4e425bb9693f0c13 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Dec 2010 22:00:18 +0100 Subject: [PATCH 069/211] Support RomFS label --- grub-core/fs/romfs.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index 342bdd733..07632e635 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -399,6 +399,40 @@ grub_romfs_close (grub_file_t file) return GRUB_ERR_NONE; } +static grub_err_t +grub_romfs_label (grub_device_t device, char **label) +{ + struct grub_romfs_data *data; + grub_err_t err; + + *label = NULL; + + data = grub_romfs_mount (device); + if (!data) + return grub_errno; + *label = grub_malloc (data->first_file + 1 + - sizeof (struct grub_romfs_superblock)); + if (!*label) + { + grub_free (data); + return grub_errno; + } + err = grub_disk_read (device->disk, 0, sizeof (struct grub_romfs_superblock), + data->first_file + - sizeof (struct grub_romfs_superblock), + *label); + if (err) + { + grub_free (data); + grub_free (*label); + *label = NULL; + return err; + } + (*label)[data->first_file - sizeof (struct grub_romfs_superblock)] = 0; + return GRUB_ERR_NONE; +} + + static struct grub_fs grub_romfs_fs = { .name = "romfs", @@ -406,6 +440,7 @@ static struct grub_fs grub_romfs_fs = .open = grub_romfs_open, .read = grub_romfs_read, .close = grub_romfs_close, + .label = grub_romfs_label, #ifdef GRUB_UTIL .reserved_first_sector = 0, #endif From e872a2dd82c6bfc27a870aff9088dfccaaa4fc02 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 18 Dec 2010 22:47:50 +0100 Subject: [PATCH 070/211] * util/grub-mkfont.c (main): Handle errors from FT_Set_Pixel_Sizes. --- ChangeLog | 4 ++++ util/grub-mkfont.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3f15bcc7b..de0a5690a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-12-18 Vladimir Serbinenko + + * util/grub-mkfont.c (main): Handle errors from FT_Set_Pixel_Sizes. + 2010-12-18 Colin Watson * grub-core/normal/term.c (print_more): Make \r or \n scroll one diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 3e24380d1..fff6a619e 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -1170,7 +1170,8 @@ main (int argc, char *argv[]) font_info.style = ft_face->style_flags; font_info.size = size; - FT_Set_Pixel_Sizes (ft_face, size, size); + if (FT_Set_Pixel_Sizes (ft_face, size, size)) + grub_util_error ("can't set %dx%d font size", size, size); add_font (&font_info, ft_face, file_format != PF2); FT_Done_Face (ft_face); } From e6533ae1547169a4ef4dd2861bd6c56a8efdc5cc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 00:43:41 +0100 Subject: [PATCH 071/211] Fix handling of UTF-16 UDF labels. * grub-core/fs/udf.c (grub_udf_iterate_dir): Move string-parsing part (read_string): .. here. (grub_udf_label): Use read_string. --- ChangeLog | 8 ++++++ grub-core/fs/udf.c | 70 +++++++++++++++++++++++++++++++--------------- 2 files changed, 55 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index de0a5690a..effab30eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-12-19 Vladimir Serbinenko + + Fix handling of UTF-16 UDF labels. + + * grub-core/fs/udf.c (grub_udf_iterate_dir): Move string-parsing part + (read_string): .. here. + (grub_udf_label): Use read_string. + 2010-12-18 Vladimir Serbinenko * util/grub-mkfont.c (main): Handle errors from FT_Set_Pixel_Sizes. diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 7041e619e..51726edf3 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -788,6 +788,43 @@ fail: return 0; } +static char * +read_string (grub_uint8_t *raw, grub_size_t sz) +{ + grub_uint16_t *utf16; + char *ret; + grub_size_t utf16len = 0; + + if (raw[0] != 8 && raw[0] != 16) + return NULL; + + if (raw[0] == 8) + { + unsigned i; + utf16len = sz - 1; + utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + if (!utf16) + return NULL; + for (i = 0; i < utf16len; i++) + utf16[i] = raw[i + 1]; + } + if (raw[0] == 16) + { + unsigned i; + utf16len = (sz - 1) / 2; + utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + if (!utf16) + return NULL; + for (i = 0; i < utf16len; i++) + utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; + } + ret = grub_malloc (utf16len * 3 + 1); + if (ret) + *grub_utf16_to_utf8 ((grub_uint8_t *) ret, utf16, utf16len) = '\0'; + grub_free (utf16); + return ret; +} + static int grub_udf_iterate_dir (grub_fshelp_node_t dir, int NESTED_FUNC_ATTR @@ -841,10 +878,8 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, else { enum grub_fshelp_filetype type; + char *filename; grub_uint8_t raw[dirent.file_ident_length]; - grub_uint16_t utf16[dirent.file_ident_length - 1]; - grub_uint8_t filename[dirent.file_ident_length * 2]; - grub_size_t utf16len = 0; type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); @@ -855,27 +890,16 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, != dirent.file_ident_length) return 0; - if (raw[0] == 8) - { - unsigned i; - utf16len = dirent.file_ident_length - 1; - for (i = 0; i < utf16len; i++) - utf16[i] = raw[i + 1]; - } - if (raw[0] == 16) - { - unsigned i; - utf16len = (dirent.file_ident_length - 1) / 2; - for (i = 0; i < utf16len; i++) - utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; - } - if (raw[0] == 8 || raw[0] == 16) - { - *grub_utf16_to_utf8 (filename, utf16, utf16len) = '\0'; + filename = read_string (raw, dirent.file_ident_length); + if (!filename) + grub_print_error (); - if (hook ((char *) filename, type, child)) - return 1; + if (filename && hook (filename, type, child)) + { + grub_free (filename); + return 1; } + grub_free (filename); } } @@ -1004,7 +1028,7 @@ grub_udf_label (grub_device_t device, char **label) if (data) { - *label = grub_strdup ((char *) &data->lvd.ident[1]); + *label = read_string (data->lvd.ident, sizeof (data->lvd.ident)); grub_free (data); } else From b85812b06f6806f988c9c57ca52f01c4eb110114 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 00:49:52 +0100 Subject: [PATCH 072/211] * grub-core/fs/affs.c (grub_affs_fs) [GRUB_UTIL]: Explicitly set reserved_first_sector to 0. * grub-core/fs/cpio.c (grub_cpio_fs) [GRUB_UTIL]: Likewise. * grub-core/fs/sfs.c (grub_sfs_fs) [GRUB_UTIL]: Likewise. * grub-core/fs/xfs.c (grub_xfs_fs) [GRUB_UTIL]: Likewise. --- ChangeLog | 8 ++++++++ grub-core/fs/affs.c | 3 +++ grub-core/fs/cpio.c | 3 +++ grub-core/fs/sfs.c | 3 +++ grub-core/fs/xfs.c | 3 +++ 5 files changed, 20 insertions(+) diff --git a/ChangeLog b/ChangeLog index effab30eb..cc3f65c86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-12-19 Vladimir Serbinenko + + * grub-core/fs/affs.c (grub_affs_fs) [GRUB_UTIL]: Explicitly set + reserved_first_sector to 0. + * grub-core/fs/cpio.c (grub_cpio_fs) [GRUB_UTIL]: Likewise. + * grub-core/fs/sfs.c (grub_sfs_fs) [GRUB_UTIL]: Likewise. + * grub-core/fs/xfs.c (grub_xfs_fs) [GRUB_UTIL]: Likewise. + 2010-12-19 Vladimir Serbinenko Fix handling of UTF-16 UDF labels. diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 3dc80752d..27e03c0c4 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -535,6 +535,9 @@ static struct grub_fs grub_affs_fs = .read = grub_affs_read, .close = grub_affs_close, .label = grub_affs_label, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif .next = 0 }; diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index c087b4f90..2c92404c3 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -354,6 +354,9 @@ static struct grub_fs grub_cpio_fs = { .open = grub_cpio_open, .read = grub_cpio_read, .close = grub_cpio_close, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif }; #ifdef MODE_USTAR diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c index 4a5005908..b49420de1 100644 --- a/grub-core/fs/sfs.c +++ b/grub-core/fs/sfs.c @@ -579,6 +579,9 @@ static struct grub_fs grub_sfs_fs = .read = grub_sfs_read, .close = grub_sfs_close, .label = grub_sfs_label, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif .next = 0 }; diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 9dffe31d1..3d773856e 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -808,6 +808,9 @@ static struct grub_fs grub_xfs_fs = .close = grub_xfs_close, .label = grub_xfs_label, .uuid = grub_xfs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, +#endif .next = 0 }; From b070525d039783869b96e0223c8142a055fffc0f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 00:52:18 +0100 Subject: [PATCH 073/211] * grub-core/fs/affs.c (grub_affs_mount): Read data->bblock.rootblock rather than assuming than rootblock is exactly in the middle. (grub_affs_label): Likewise. --- ChangeLog | 6 ++++++ grub-core/fs/affs.c | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc3f65c86..8f459f198 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-19 Vladimir Serbinenko + + * grub-core/fs/affs.c (grub_affs_mount): Read data->bblock.rootblock + rather than assuming than rootblock is exactly in the middle. + (grub_affs_label): Likewise. + 2010-12-19 Vladimir Serbinenko * grub-core/fs/affs.c (grub_affs_fs) [GRUB_UTIL]: Explicitly set diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 27e03c0c4..40be4b2f6 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -208,7 +208,7 @@ grub_affs_mount (grub_disk_t disk) rblock = (struct grub_affs_rblock *) rootblock; /* Read the rootblock. */ - grub_disk_read (disk, (disk->total_sectors >> 1) + blocksize, 0, + grub_disk_read (disk, grub_be_to_cpu32 (data->bblock.rootblock), 0, GRUB_DISK_SECTOR_SIZE * 16, rootblock); if (grub_errno) goto fail; @@ -240,7 +240,7 @@ grub_affs_mount (grub_disk_t disk) data->disk = disk; data->htsize = grub_be_to_cpu32 (rblock->htsize); data->diropen.data = data; - data->diropen.block = (disk->total_sectors >> 1); + data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock); grub_free (rootblock); @@ -507,7 +507,7 @@ grub_affs_label (grub_device_t device, char **label) { /* The rootblock maps quite well on a file header block, it's something we can use here. */ - grub_disk_read (data->disk, disk->total_sectors >> 1, + grub_disk_read (data->disk, grub_be_to_cpu32 (data->bblock.rootblock), data->blocksize * (GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION), sizeof (file), &file); From 1c95b6d2bfb721df4859414a4f31ac8ed9c7bc8d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 23 Dec 2010 12:11:44 +0000 Subject: [PATCH 074/211] Move video/colors.c into video.mod. --- ChangeLog.parse-color | 5 ++--- grub-core/Makefile.core.def | 7 +------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/ChangeLog.parse-color b/ChangeLog.parse-color index b241f3b73..81628e89f 100644 --- a/ChangeLog.parse-color +++ b/ChangeLog.parse-color @@ -1,4 +1,4 @@ -2010-12-10 Colin Watson +2010-12-23 Colin Watson Move gfxmenu color handling to video, so that gfxterm can use it too. @@ -30,8 +30,7 @@ * grub-core/Makefile.core.def (kernel) [videoinkernel]: Add video/colors.c. (gfxmenu): Remove gfxmenu/named_colors.c. - (video_colors) [videomodules]: New module, containing - video/colors.c. + (video) [videomodules]: Add video/colors.c. Add a background_color command. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index fdf7d0826..8566c79fb 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1442,12 +1442,6 @@ module = { enable = i386_pc; }; -module = { - name = video_colors; - common = video/colors.c; - enable = videomodules; -}; - module = { name = video_fb; common = video/fb/video_fb.c; @@ -1460,6 +1454,7 @@ module = { module = { name = video; common = video/video.c; + common = video/colors.c; enable = videomodules; }; From af4e4a875acc4398a211b8e15ffa8ee40b1efdce Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 23 Dec 2010 12:19:55 +0000 Subject: [PATCH 075/211] return GRUB_ERR_NONE instead of setting grub_errno --- grub-core/term/gfxterm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 09363918a..8a75df93c 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -1235,9 +1235,7 @@ grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), /* Mark whole screen as dirty. */ dirty_region_add (0, 0, window.width, window.height); - /* All was ok. */ - grub_errno = GRUB_ERR_NONE; - return grub_errno; + return GRUB_ERR_NONE; } static struct grub_term_output grub_video_term = From b28fd807eb6e6ec74964715e0bfd3c32b0dbb449 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Dec 2010 00:38:20 +0100 Subject: [PATCH 076/211] freedos support --- docs/grub.texi | 4 + grub-core/Makefile.core.def | 6 ++ grub-core/lib/i386/relocator.c | 2 + grub-core/lib/i386/relocator16.S | 7 +- grub-core/loader/i386/pc/freedos.c | 136 +++++++++++++++++++++++++++++ include/grub/i386/relocator.h | 1 + 6 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 grub-core/loader/i386/pc/freedos.c diff --git a/docs/grub.texi b/docs/grub.texi index 54a2d8791..d9500fb52 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -3305,6 +3305,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel @item @tab BIOS @tab Coreboot @item BIOS chainloading @tab yes @tab no (1) @item NTLDR @tab yes @tab no (1) +@item Freedos @tab yes @tab no (1) @item FreeBSD bootloader @tab yes @tab crashes (1) @item 32-bit kFreeBSD @tab yes @tab crashes (2,6) @item 64-bit kFreeBSD @tab yes @tab crashes (2,6) @@ -3329,6 +3330,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel @item @tab Multiboot @tab Qemu @item BIOS chainloading @tab no (1) @tab no (1) @item NTLDR @tab no (1) @tab no (1) +@item FreeDOS @tab no (1) @tab no (1) @item FreeBSD bootloader @tab crashes (1) @tab crashes (1) @item 32-bit kFreeBSD @tab crashes (6) @tab crashes (6) @item 64-bit kFreeBSD @tab crashes (6) @tab crashes (6) @@ -3353,6 +3355,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel @item @tab 32-bit EFI @tab 64-bit EFI @item BIOS chainloading @tab no (1) @tab no (1) @item NTLDR @tab no (1) @tab no (1) +@item FreeDOS @tab no (1) @tab no (1) @item FreeBSD bootloader @tab crashes (1) @tab crashes (1) @item 32-bit kFreeBSD @tab headless @tab headless @item 64-bit kFreeBSD @tab headless @tab headless @@ -3377,6 +3380,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel @item @tab IEEE1275 @item BIOS chainloading @tab no (1) @item NTLDR @tab no (1) +@item FreeDOS @tab no (1) @item FreeBSD bootloader @tab crashes (1) @item 32-bit kFreeBSD @tab crashes (6) @item 64-bit kFreeBSD @tab crashes (6) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 37c0ce970..da309d6d9 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1158,6 +1158,12 @@ module = { enable = i386_pc; }; +module = { + name = freedos; + i386_pc = loader/i386/pc/freedos.c; + enable = i386_pc; +}; + module = { name = multiboot2; cppflags = "-DGRUB_USE_MULTIBOOT2"; diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c index 1bc4240c3..2f10feb5e 100644 --- a/grub-core/lib/i386/relocator.c +++ b/grub-core/lib/i386/relocator.c @@ -50,6 +50,7 @@ extern grub_uint16_t grub_relocator16_gs; extern grub_uint16_t grub_relocator16_ss; extern grub_uint16_t grub_relocator16_sp; extern grub_uint32_t grub_relocator16_edx; +extern grub_uint32_t grub_relocator16_ebx; extern grub_uint8_t grub_relocator32_start; extern grub_uint8_t grub_relocator32_end; @@ -212,6 +213,7 @@ grub_relocator16_boot (struct grub_relocator *rel, grub_relocator16_ss = state.ss; grub_relocator16_sp = state.sp; + grub_relocator16_ebx = state.ebx; grub_relocator16_edx = state.edx; grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start, diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S index c3768f4eb..c6d38eba4 100644 --- a/grub-core/lib/i386/relocator16.S +++ b/grub-core/lib/i386/relocator16.S @@ -136,7 +136,12 @@ VARIABLE(grub_relocator16_sp) .byte 0x66, 0xba VARIABLE(grub_relocator16_edx) .long 0 - + + /* movw imm32, %ebx. */ + .byte 0x66, 0xbb +VARIABLE(grub_relocator16_ebx) + .long 0 + /* Cleared direction flag is of no problem with any current payload and makes this implementation easier. */ cld diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c new file mode 100644 index 000000000..67d97e246 --- /dev/null +++ b/grub-core/loader/i386/pc/freedos.c @@ -0,0 +1,136 @@ +/* chainloader.c - boot another boot loader */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2007,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_dl_t my_mod; +static struct grub_relocator *rel; +static grub_uint32_t ebx = 0xffffffff; + +#define GRUB_FREEDOS_SEGMENT 0x60 +#define GRUB_FREEDOS_STACK_SEGMENT 0x1fe0 +#define GRUB_FREEDOS_STACK_POINTER 0x8000 + +static grub_err_t +grub_freedos_boot (void) +{ + struct grub_relocator16_state state = { + .cs = GRUB_FREEDOS_SEGMENT, + .ip = 0, + .ds = 0, + .es = 0, + .fs = 0, + .gs = 0, + .ss = GRUB_FREEDOS_STACK_SEGMENT, + .sp = GRUB_FREEDOS_STACK_POINTER, + .ebx = ebx, + .edx = 0 + }; + grub_video_set_mode ("text", 0, 0); + + return grub_relocator16_boot (rel, state); +} + +static grub_err_t +grub_freedos_unload (void) +{ + grub_relocator_unload (rel); + rel = NULL; + grub_dl_unref (my_mod); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_err_t err; + void *kernelsys; + grub_size_t kernelsyssize; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); + + grub_dl_ref (my_mod); + + rel = grub_relocator_new (); + if (!rel) + goto fail; + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + ebx = grub_get_root_biosnumber (); + + kernelsyssize = grub_file_size (file); + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4, + kernelsyssize); + if (err) + goto fail; + kernelsys = get_virtual_current_address (ch); + } + + if (grub_file_read (file, kernelsys, kernelsyssize) + != (grub_ssize_t) ntldrsize) + goto fail; + + grub_loader_set (grub_freedos_boot, grub_freedos_unload, 1); + return GRUB_ERR_NONE; + + fail: + + if (file) + grub_file_close (file); + + grub_ntldr_unload (); + + return grub_errno; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(freedos) +{ + cmd = grub_register_command ("freedos", grub_cmd_freedos, + 0, N_("Load FreeDOS kernel.sys.")); + my_mod = mod; +} + +GRUB_MOD_FINI(freedos) +{ + grub_unregister_command (cmd); +} diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h index 6ff5c6631..778049eef 100644 --- a/include/grub/i386/relocator.h +++ b/include/grub/i386/relocator.h @@ -46,6 +46,7 @@ struct grub_relocator16_state grub_uint16_t ss; grub_uint16_t sp; grub_uint16_t ip; + grub_uint32_t ebx; grub_uint32_t edx; }; From af36812f5cf8d15cdb00a80681a2918bd07a9765 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Dec 2010 00:57:03 +0100 Subject: [PATCH 077/211] fix a compilation error --- grub-core/loader/i386/pc/freedos.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c index 67d97e246..0ae815490 100644 --- a/grub-core/loader/i386/pc/freedos.c +++ b/grub-core/loader/i386/pc/freedos.c @@ -97,7 +97,7 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)), kernelsyssize = grub_file_size (file); { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4, + err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_SEGMENT << 4, kernelsyssize); if (err) goto fail; @@ -105,7 +105,7 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)), } if (grub_file_read (file, kernelsys, kernelsyssize) - != (grub_ssize_t) ntldrsize) + != (grub_ssize_t) kernelsyssize) goto fail; grub_loader_set (grub_freedos_boot, grub_freedos_unload, 1); @@ -116,7 +116,7 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)), if (file) grub_file_close (file); - grub_ntldr_unload (); + grub_freedos_unload (); return grub_errno; } From b9cd13659cce5dd2414e962c02042c9ece90b918 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 31 Dec 2010 15:22:36 +0100 Subject: [PATCH 078/211] Simplify the AFFS checksum computation. --- grub-core/fs/affs.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index e4b487a7e..e05c166a9 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -174,7 +174,6 @@ grub_affs_mount (grub_disk_t disk) struct grub_affs_rblock *rblock; int checksum = 0; - int checksumr = 0; int blocksize = 0; data = grub_malloc (sizeof (struct grub_affs_data)); @@ -224,8 +223,6 @@ grub_affs_mount (grub_disk_t disk) /* The filesystem blocksize is not stored anywhere in the filesystem itself. One way to determine it is reading blocks for the rootblock until the checksum is correct. */ - checksumr = grub_be_to_cpu32 (rblock->checksum); - rblock->checksum = 0; for (blocksize = 0; blocksize < 8; blocksize++) { grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize; @@ -234,10 +231,10 @@ grub_affs_mount (grub_disk_t disk) for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++) checksum += grub_be_to_cpu32 (currblock[i]); - if (checksumr == -checksum) + if (checksum == 0) break; } - if (-checksum != checksumr) + if (checksum != 0) { grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined"); goto fail; From fb17547ca89991f33d269cc01af711e198ab1eb0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 31 Dec 2010 15:23:06 +0100 Subject: [PATCH 079/211] Check amiga partmap checksum --- grub-core/partmap/amiga.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c index 1e0f23402..803e2e14f 100644 --- a/grub-core/partmap/amiga.c +++ b/grub-core/partmap/amiga.c @@ -37,7 +37,7 @@ struct grub_amiga_rdsk grub_uint32_t partitionlst; grub_uint32_t fslst; - /* The other information is not important for us. */ + grub_uint32_t unused[128 - 9]; } __attribute__ ((packed)); struct grub_amiga_partition @@ -65,12 +65,24 @@ struct grub_amiga_partition grub_uint32_t highcyl; grub_uint32_t firstcyl; + grub_uint32_t unused[128 - 44]; } __attribute__ ((packed)); static struct grub_partition_map grub_amiga_partition_map; +static grub_uint32_t +amiga_partition_map_checksum (void *buf, grub_size_t sz) +{ + grub_uint32_t *ptr = buf; + grub_uint32_t r = 0; + sz /= sizeof (grub_uint32_t); + for (; sz; sz--, ptr++) + r += grub_be_to_cpu32 (*ptr); + return r; +} + static grub_err_t amiga_partition_map_iterate (grub_disk_t disk, int (*hook) (grub_disk_t disk, @@ -90,7 +102,8 @@ amiga_partition_map_iterate (grub_disk_t disk, return grub_errno; if (grub_memcmp (rdsk.magic, GRUB_AMIGA_RDSK_MAGIC, - sizeof (rdsk.magic)) == 0) + sizeof (rdsk.magic)) == 0 + && amiga_partition_map_checksum (&rdsk, sizeof (rdsk)) == 0) { /* Found the first PART block. */ next = grub_be_to_cpu32 (rdsk.partitionlst); @@ -112,7 +125,8 @@ amiga_partition_map_iterate (grub_disk_t disk, return grub_errno; if (grub_memcmp (apart.magic, GRUB_AMIGA_PART_MAGIC, - sizeof (apart.magic)) == 0) + sizeof (apart.magic)) == 0 + && amiga_partition_map_checksum (&apart, sizeof (apart)) == 0) /* Calculate the first block and the size of the partition. */ part.start = (grub_be_to_cpu32 (apart.lowcyl) From 3a04c65d008246c29d8a0b86fb66770ac6d6634f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 Jan 2011 15:13:03 +0100 Subject: [PATCH 080/211] Always add libgcc.h --- grub-core/Makefile.am | 4 +--- include/grub/libgcc.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 5d13d0313..7fa00b744 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -74,6 +74,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h if COND_i386_pc KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h @@ -132,7 +133,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap_scale.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/serial.h @@ -140,11 +140,9 @@ endif if COND_powerpc_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h endif if COND_sparc64_ieee1275 -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h endif diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h index 703182577..100c8667b 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -53,7 +53,7 @@ void EXPORT_FUNC (__udivdi3) (void); # ifdef HAVE___DIVSI3 void EXPORT_FUNC (__divsi3) (void); # endif -# ifdef HAVE___UMODSI3 +# ifdef HAVE___MODSI3 void EXPORT_FUNC (__modsi3) (void); # endif #endif From 52f65ea0bc9c3d36a0691a330eb2131df7cacc6d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 Jan 2011 15:28:39 +0100 Subject: [PATCH 081/211] add moddi3 and divdi3 --- configure.ac | 2 +- include/grub/libgcc.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ca886b5dc..4c710748c 100644 --- a/configure.ac +++ b/configure.ac @@ -542,7 +542,7 @@ CFLAGS="$CFLAGS -Wl,--defsym,abort=main" fi # Check for libgcc symbols -AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3) +AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3) if test "x$TARGET_APPLE_CC" = x1 ; then CFLAGS="$TARGET_CFLAGS -nostdlib" diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h index 100c8667b..be600220e 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -50,6 +50,12 @@ void EXPORT_FUNC (__umoddi3) (void); # ifdef HAVE___UDIVDI3 void EXPORT_FUNC (__udivdi3) (void); # endif +# ifdef HAVE___MODDI3 +void EXPORT_FUNC (__moddi3) (void); +# endif +# ifdef HAVE___DIVDI3 +void EXPORT_FUNC (__divdi3) (void); +# endif # ifdef HAVE___DIVSI3 void EXPORT_FUNC (__divsi3) (void); # endif From 6f49d0aacb1a26d756faa849ea5b18d1322091d5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 Jan 2011 15:53:31 +0100 Subject: [PATCH 082/211] Add missing cache.c --- grub-core/Makefile.core.def | 1 + grub-core/kern/emu/cache.c | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 grub-core/kern/emu/cache.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index b953adfb9..801ad6d7c 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -158,6 +158,7 @@ kernel = { emu = kern/emu/misc.c; emu = kern/emu/mm.c; emu = kern/emu/time.c; + emu = kern/emu/cache.c; videoinkernel = lib/arg.c; videoinkernel = term/gfxterm.c; diff --git a/grub-core/kern/emu/cache.c b/grub-core/kern/emu/cache.c new file mode 100644 index 000000000..bdff146ef --- /dev/null +++ b/grub-core/kern/emu/cache.c @@ -0,0 +1,10 @@ + +#include + +void __clear_cache (char *beg, char *end); + +void +grub_arch_sync_caches (void *address, grub_size_t len) +{ + __clear_cache (address, (char *) address + len); +} From f9c30af6d08a6d2b0c3e831d116c37dc1d1d7c78 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 14:09:58 +0100 Subject: [PATCH 083/211] Succesfully loaded return-only module on ia64-emu --- grub-core/kern/dl.c | 49 ++++++- grub-core/kern/emu/cache.S | 1 + grub-core/kern/emu/cache.c | 3 + grub-core/kern/emu/full.c | 9 ++ grub-core/kern/emu/lite.c | 2 + grub-core/kern/ia64/dl.c | 288 +++++++++++++++++++++++++++++++++++++ include/grub/dl.h | 20 ++- include/grub/types.h | 3 + 8 files changed, 368 insertions(+), 7 deletions(-) create mode 100644 grub-core/kern/ia64/dl.c diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 02d785b9b..2f2493fca 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -37,6 +37,10 @@ #define GRUB_MODULES_MACHINE_READONLY #endif +#ifdef GRUB_MACHINE_EMU +#include +#endif + grub_dl_t grub_dl_head = 0; @@ -233,11 +237,24 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) if (s->sh_flags & SHF_ALLOC) { grub_dl_segment_t seg; + grub_size_t tramp_size = 0; seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg)); if (! seg) return grub_errno; + tramp_size = grub_arch_dl_get_tramp_size (e, i); + if (tramp_size && s->sh_addralign < GRUB_ARCH_DL_TRAMP_ALIGN) + { + s->sh_addralign = GRUB_ARCH_DL_TRAMP_ALIGN; + s->sh_size = ALIGN_UP (s->sh_size, GRUB_ARCH_DL_TRAMP_ALIGN) + tramp_size; + } +#ifdef GRUB_MACHINE_EMU + if (s->sh_addralign < 8192) + s->sh_addralign = 8192; + s->sh_size = ALIGN_UP (s->sh_size, 8192); +#endif + if (s->sh_size) { void *addr; @@ -260,6 +277,10 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) } seg->addr = addr; +#ifdef GRUB_MACHINE_EMU + if (s->sh_flags & SHF_EXECINSTR) + mprotect (addr, s->sh_size, PROT_READ | PROT_WRITE | PROT_EXEC); +#endif } else seg->addr = 0; @@ -343,9 +364,9 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) return grub_errno; if (grub_strcmp (name, "grub_mod_init") == 0) - mod->init = (void (*) (grub_dl_t)) sym->st_value; + mod->init = sym->st_value; else if (grub_strcmp (name, "grub_mod_fini") == 0) - mod->fini = (void (*) (void)) sym->st_value; + mod->fini = sym->st_value; break; case STT_SECTION: @@ -370,7 +391,16 @@ static void grub_dl_call_init (grub_dl_t mod) { if (mod->init) - (mod->init) (mod); + { +#ifndef __ia64__ + ((void (*) (grub_dl_t)) mod->init) (mod); +#else + char *jmp[2]; + jmp[0] = (char *) mod->init; + jmp[1] = mod->gp; + ((void (*) (grub_dl_t)) jmp) (mod); +#endif + } } static grub_err_t @@ -533,7 +563,7 @@ grub_dl_load_core (void *addr, grub_size_t size) grub_dl_flush_cache (mod); grub_dprintf ("modules", "module name: %s\n", mod->name); - grub_dprintf ("modules", "init function: %p\n", mod->init); + grub_dprintf ("modules", "init function: %" PRIxGRUB_ADDR "\n", mod->init); grub_dl_call_init (mod); if (grub_dl_add (mod)) @@ -633,7 +663,16 @@ grub_dl_unload (grub_dl_t mod) return 0; if (mod->fini) - (mod->fini) (); + { +#ifndef __ia64__ + ((void (*) (void)) mod->fini) (); +#else + char *jmp[2]; + jmp[0] = (char *) mod->fini; + jmp[1] = mod->gp; + ((void (*) (void)) jmp) (); +#endif + } grub_dl_remove (mod); grub_dl_unregister_symbols (mod); diff --git a/grub-core/kern/emu/cache.S b/grub-core/kern/emu/cache.S index 90a5b5396..99637762a 100644 --- a/grub-core/kern/emu/cache.S +++ b/grub-core/kern/emu/cache.S @@ -10,6 +10,7 @@ #include "../mips/cache.S" #elif defined(__powerpc__) #include "../powerpc/cache.S" +#elif defined(__ia64__) #else #error "No target cpu type is defined" #endif diff --git a/grub-core/kern/emu/cache.c b/grub-core/kern/emu/cache.c index bdff146ef..543e457e5 100644 --- a/grub-core/kern/emu/cache.c +++ b/grub-core/kern/emu/cache.c @@ -1,4 +1,5 @@ +#if defined(__ia64__) #include void __clear_cache (char *beg, char *end); @@ -8,3 +9,5 @@ grub_arch_sync_caches (void *address, grub_size_t len) { __clear_cache (address, (char *) address + len); } +#endif + diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 0bd33337f..0396d0ab4 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -48,3 +48,12 @@ grub_emu_init (void) { grub_no_autoload = 1; } + +#ifdef __ia64__ +grub_size_t +grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), + unsigned sec __attribute__ ((unused))) +{ + return ~(grub_size_t)0; +} +#endif diff --git a/grub-core/kern/emu/lite.c b/grub-core/kern/emu/lite.c index 9b3728717..5d3588bd0 100644 --- a/grub-core/kern/emu/lite.c +++ b/grub-core/kern/emu/lite.c @@ -15,6 +15,8 @@ #include "../mips/dl.c" #elif defined(__powerpc__) #include "../powerpc/dl.c" +#elif defined(__ia64__) +#include "../ia64/dl.c" #else #error "No target cpu type is defined" #endif diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c new file mode 100644 index 000000000..2b87577a4 --- /dev/null +++ b/grub-core/kern/ia64/dl.c @@ -0,0 +1,288 @@ +/* dl.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf_Ehdr *e = ehdr; + + /* Check the magic numbers. */ + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2LSB + || e->e_machine != EM_IA_64) + return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic"); + + return GRUB_ERR_NONE; +} + +#define MASK20 ((1 << 20) - 1) +#define MASK19 ((1 << 19) - 1) + +static void +add_value_to_slot13_20 (Elf_Word *addr, grub_uint32_t value, int slot) +{ + grub_uint32_t *p __attribute__ ((aligned (1))); + switch (slot) + { + case 0: + p = (grub_uint32_t *) (addr + 2); + *p = (((((*p >> 2) & MASK20) + value) & MASK20) << 2) | (*p & ~(MASK20 << 2)); + break; + case 1: + p = (grub_uint32_t *) ((grub_uint8_t *) addr + 7); + *p = (((((*p >> 3) & MASK20) + value) & MASK20) << 3) | (*p & ~(MASK20 << 3)); + break; + case 2: + p = (grub_uint32_t *) ((grub_uint8_t *) addr + 12); + *p = (((((*p >> 4) & MASK20) + value) & MASK20) << 4) | (*p & ~(MASK20 << 4)); + break; + } +} + +static grub_uint8_t nopm[5] = + { + /* [MLX] nop.m 0x0 */ + 0x05, 0x00, 0x00, 0x00, 0x01 + }; + +static grub_uint8_t jump[0x20] = + { + /* ld8 r16=[r15],8 */ + 0x02, 0x80, 0x20, 0x1e, 0x18, 0x14, + /* mov r14=r1;; */ + 0xe0, 0x00, 0x04, 0x00, 0x42, 0x00, + /* nop.i 0x0 */ + 0x00, 0x00, 0x04, 0x00, + /* ld8 r1=[r15] */ + 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, + /* mov b6=r16 */ + 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, + /* br.few b6;; */ + 0x60, 0x00, 0x80, 0x00 + }; + +struct ia64_trampoline +{ + /* nop.m */ + grub_uint8_t nop[5]; + /* movl r15 = addr*/ + grub_uint8_t addr_hi[6]; + grub_uint8_t e0; + grub_uint8_t addr_lo[4]; + grub_uint8_t jump[0x20]; +}; + +static void +make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr) +{ + grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); + tr->addr_hi[0] = ((addr & 0xc00000) >> 18); + tr->addr_hi[1] = (addr >> 24) & 0xff; + tr->addr_hi[2] = (addr >> 32) & 0xff; + tr->addr_hi[3] = (addr >> 40) & 0xff; + tr->addr_hi[4] = (addr >> 48) & 0xff; + tr->addr_hi[5] = (addr >> 56) & 0xff; + tr->e0 = 0xe0; + tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01; + tr->addr_lo[1] = ((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11) | ((addr & 0x200000) >> 17); + tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19); + tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60; + grub_memcpy (tr->jump, jump, sizeof (tr->jump)); +} + +grub_size_t +grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) +{ + const Elf_Ehdr *e = ehdr; + int cnt = 0; + const Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + + /* Find a symbol table. */ + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return 0; + + entsize = s->sh_entsize; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + Elf_Rela *rel, *max; + + if (s->sh_info != sec) + continue; + + for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; rel++) + if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) + cnt++; + } + + return cnt * sizeof (struct ia64_trampoline); +} + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf_Ehdr *e = ehdr; + Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + grub_uint64_t *gp, *gpptr; + grub_size_t gp_size = 0; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_REL) + { + grub_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf_Rel *rel, *max; + + for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + switch (ELF_R_TYPE (rel->r_info)) + { + default: break; + } + } + } + + if (gp_size > MASK19) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "gp too big"); + + gpptr = gp = grub_malloc (gp_size); + if (!gp) + return grub_errno; + mod->gp = (char *) gp; + + /* Find a symbol table. */ + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); + + entsize = s->sh_entsize; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + grub_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf_Rela *rel, *max; + struct ia64_trampoline *tr; + + for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + { + Elf_Word *addr; + Elf_Sym *sym; + grub_uint64_t value; + int slot = 0; + + if (seg->size < (rel->r_offset & ~3)) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + tr = (void *) ((char *) seg->addr + ALIGN_UP (seg->size, GRUB_ARCH_DL_TRAMP_ALIGN)); + + if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) + { + addr = (Elf_Word *) ((char *) seg->addr + (rel->r_offset & ~3)); + slot = rel->r_offset & 3; + } + else + addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + entsize * ELF_R_SYM (rel->r_info)); + + /* On the PPC the value does not have an explicit + addend, add it. */ + value = sym->st_value + rel->r_addend; + switch (ELF_R_TYPE (rel->r_info)) + { + case R_IA64_PCREL21B: + { + grub_uint64_t noff; + make_trampoline (tr, value); + noff = ((char *) tr - (char *) addr) >> 4; + tr++; + if (noff & ~MASK19) + return grub_error (GRUB_ERR_BAD_OS, + "trampoline offset too big"); + add_value_to_slot13_20 (addr, noff, slot); + } + break; + case R_IA64_SEGREL64LSB: + *(grub_uint64_t *) addr += value - rel->r_offset; + break; + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "this relocation (0x%x) is not implemented yet", + ELF_R_TYPE (rel->r_info)); + } + } + } + } + + return GRUB_ERR_NONE; +} diff --git a/include/grub/dl.h b/include/grub/dl.h index afc4af41a..e04285280 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -90,8 +90,11 @@ struct grub_dl grub_dl_dep_t dep; grub_dl_segment_t segment; Elf_Sym *symtab; - void (*init) (struct grub_dl *mod); - void (*fini) (void); + grub_addr_t init; + grub_addr_t fini; +#ifdef __ia64__ + char *gp; +#endif struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -119,4 +122,17 @@ grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); void grub_arch_dl_init_linker (void); #endif +#ifdef __ia64__ +grub_size_t grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec); +#define GRUB_ARCH_DL_TRAMP_ALIGN 16 +#else +static inline grub_size_t +grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), int sec __attribute__ ((unused))) +{ + return 0; +} +#define GRUB_ARCH_DL_TRAMP_ALIGN 1 +#endif + + #endif /* ! GRUB_DL_H */ diff --git a/include/grub/types.h b/include/grub/types.h index 4499e4538..b3aa69c1c 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -95,8 +95,10 @@ typedef grub_int64_t grub_ssize_t; # if GRUB_CPU_SIZEOF_LONG == 8 # define PRIxGRUB_SIZE "lx" +# define PRIxGRUB_ADDR "lx" # else # define PRIxGRUB_SIZE "llx" +# define PRIxGRUB_ADDR "llx" # endif #else typedef grub_uint32_t grub_addr_t; @@ -104,6 +106,7 @@ typedef grub_uint32_t grub_size_t; typedef grub_int32_t grub_ssize_t; # define PRIxGRUB_SIZE "x" +# define PRIxGRUB_ADDR "x" #endif #if GRUB_CPU_SIZEOF_LONG == 8 From daca6c5f45406137290e008ae0ef363624bc1887 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 14:39:23 +0100 Subject: [PATCH 084/211] ltoff relocation support --- grub-core/kern/ia64/dl.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 2b87577a4..24fa01b90 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -187,6 +187,10 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) rel++) switch (ELF_R_TYPE (rel->r_info)) { + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + gp_size += 8; + break; default: break; } } @@ -275,6 +279,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) case R_IA64_SEGREL64LSB: *(grub_uint64_t *) addr += value - rel->r_offset; break; + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + *gpptr = value; + add_value_to_slot13_20 (addr, (gpptr - gp) * sizeof (grub_uint64_t), slot); + gpptr++; + break; + + /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */ + case R_IA64_LDXMOV: + break; default: return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "this relocation (0x%x) is not implemented yet", From 73911575dd67eaa09837fe0f691655553c3dea69 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 14:58:57 +0100 Subject: [PATCH 085/211] support for registering functions from modules (not tested yet) --- grub-core/kern/dl.c | 20 +++++++++++++++++--- grub-core/kern/emu/full.c | 8 ++++++++ grub-core/kern/ia64/dl.c | 30 ++++++++++++++++++++---------- include/grub/dl.h | 9 +++++++++ 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 2f2493fca..9dfff5287 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -360,9 +360,22 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, sym->st_shndx); if (bind != STB_LOCAL) - if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) - return grub_errno; - + { +#ifdef __ia64__ + /* FIXME: free descriptor once it's not used anymore. */ + char **desc; + desc = grub_malloc (2 * sizeof (char *)); + if (!desc) + return grub_errno; + desc[0] = (void *) sym->st_value; + desc[1] = mod->gp; + if (grub_dl_register_symbol (name, (void *) desc, mod)) + return grub_errno; +#else + if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + return grub_errno; +#endif + } if (grub_strcmp (name, "grub_mod_init") == 0) mod->init = sym->st_value; else if (grub_strcmp (name, "grub_mod_fini") == 0) @@ -552,6 +565,7 @@ grub_dl_load_core (void *addr, grub_size_t size) if (grub_dl_resolve_name (mod, e) || grub_dl_resolve_dependencies (mod, e) || grub_dl_load_segments (mod, e) + || grub_arch_dl_allocate_gp (mod, e) || grub_dl_resolve_symbols (mod, e) || grub_arch_dl_relocate_symbols (mod, e)) { diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 0396d0ab4..67a125301 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -56,4 +56,12 @@ grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), { return ~(grub_size_t)0; } + +grub_err_t +grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)), + const void *ehdr __attribute__ ((unused))) +{ + return GRUB_ERR_BAD_MODULE; +} + #endif diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 24fa01b90..1fbe185b4 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -154,16 +154,13 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) return cnt * sizeof (struct ia64_trampoline); } -/* Relocate symbols. */ grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr) { - Elf_Ehdr *e = ehdr; - Elf_Shdr *s; - Elf_Word entsize; - unsigned i; - grub_uint64_t *gp, *gpptr; grub_size_t gp_size = 0; + const Elf_Ehdr *e = ehdr; + const Elf_Shdr *s; + unsigned i; for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); i < e->e_shnum; @@ -199,10 +196,23 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) if (gp_size > MASK19) return grub_error (GRUB_ERR_OUT_OF_RANGE, "gp too big"); - gpptr = gp = grub_malloc (gp_size); - if (!gp) + mod->gp = grub_malloc (gp_size); + if (!mod->gp) return grub_errno; - mod->gp = (char *) gp; + return GRUB_ERR_NONE; +} + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf_Ehdr *e = ehdr; + Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + grub_uint64_t *gp, *gpptr; + + gp = gpptr = (grub_uint64_t *) mod->gp; /* Find a symbol table. */ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); diff --git a/include/grub/dl.h b/include/grub/dl.h index e04285280..c43c30ca7 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -124,6 +124,8 @@ void grub_arch_dl_init_linker (void); #ifdef __ia64__ grub_size_t grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec); +grub_err_t grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr); + #define GRUB_ARCH_DL_TRAMP_ALIGN 16 #else static inline grub_size_t @@ -131,6 +133,13 @@ grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), int sec { return 0; } +static inline grub_err_t +grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)), + const void *ehdr __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} + #define GRUB_ARCH_DL_TRAMP_ALIGN 1 #endif From bbbf84350e06a97de1254fa0866d317ab40c95a7 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 19:20:28 +0100 Subject: [PATCH 086/211] Working hello.mod with extcmd.mod --- grub-core/kern/dl.c | 46 ++++++++----------- grub-core/kern/ia64/dl.c | 99 ++++++++++++++++++++++++++++------------ 2 files changed, 88 insertions(+), 57 deletions(-) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 9dfff5287..0ccdbe03b 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -238,28 +238,32 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) { grub_dl_segment_t seg; grub_size_t tramp_size = 0; + grub_size_t alsize, align; seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg)); if (! seg) return grub_errno; + alsize = s->sh_size; + align = s->sh_addralign; tramp_size = grub_arch_dl_get_tramp_size (e, i); - if (tramp_size && s->sh_addralign < GRUB_ARCH_DL_TRAMP_ALIGN) + if (tramp_size && align < GRUB_ARCH_DL_TRAMP_ALIGN) { - s->sh_addralign = GRUB_ARCH_DL_TRAMP_ALIGN; - s->sh_size = ALIGN_UP (s->sh_size, GRUB_ARCH_DL_TRAMP_ALIGN) + tramp_size; + align = GRUB_ARCH_DL_TRAMP_ALIGN; + alsize = ALIGN_UP (alsize, GRUB_ARCH_DL_TRAMP_ALIGN); } + alsize += tramp_size; #ifdef GRUB_MACHINE_EMU - if (s->sh_addralign < 8192) - s->sh_addralign = 8192; - s->sh_size = ALIGN_UP (s->sh_size, 8192); + if (align < 8192 * 16) + align = 8192 * 16; + alsize = ALIGN_UP (alsize, 8192 * 16); #endif - if (s->sh_size) + if (alsize) { void *addr; - addr = grub_memalign (s->sh_addralign, s->sh_size); + addr = grub_memalign (align, alsize); if (! addr) { grub_free (seg); @@ -279,7 +283,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) seg->addr = addr; #ifdef GRUB_MACHINE_EMU if (s->sh_flags & SHF_EXECINSTR) - mprotect (addr, s->sh_size, PROT_READ | PROT_WRITE | PROT_EXEC); + mprotect (addr, alsize, PROT_READ | PROT_WRITE | PROT_EXEC); #endif } else @@ -359,9 +363,8 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) case STT_FUNC: sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, sym->st_shndx); - if (bind != STB_LOCAL) - { #ifdef __ia64__ + { /* FIXME: free descriptor once it's not used anymore. */ char **desc; desc = grub_malloc (2 * sizeof (char *)); @@ -371,10 +374,13 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) desc[1] = mod->gp; if (grub_dl_register_symbol (name, (void *) desc, mod)) return grub_errno; -#else + sym->st_value = (grub_addr_t) desc; + } +#endif + if (bind != STB_LOCAL) + { if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) return grub_errno; -#endif } if (grub_strcmp (name, "grub_mod_init") == 0) mod->init = sym->st_value; @@ -405,14 +411,7 @@ grub_dl_call_init (grub_dl_t mod) { if (mod->init) { -#ifndef __ia64__ ((void (*) (grub_dl_t)) mod->init) (mod); -#else - char *jmp[2]; - jmp[0] = (char *) mod->init; - jmp[1] = mod->gp; - ((void (*) (grub_dl_t)) jmp) (mod); -#endif } } @@ -678,14 +677,7 @@ grub_dl_unload (grub_dl_t mod) if (mod->fini) { -#ifndef __ia64__ ((void (*) (void)) mod->fini) (); -#else - char *jmp[2]; - jmp[0] = (char *) mod->fini; - jmp[1] = mod->gp; - ((void (*) (void)) jmp) (); -#endif } grub_dl_remove (mod); diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 1fbe185b4..55b50ff69 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -41,23 +41,62 @@ grub_arch_dl_check_header (void *ehdr) #define MASK20 ((1 << 20) - 1) #define MASK19 ((1 << 19) - 1) -static void -add_value_to_slot13_20 (Elf_Word *addr, grub_uint32_t value, int slot) +struct unaligned_uint32 { - grub_uint32_t *p __attribute__ ((aligned (1))); - switch (slot) + grub_uint32_t val; +} __attribute__ ((packed)); + +static void +add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value) +{ + struct unaligned_uint32 *p; + switch (addr & 3) { case 0: - p = (grub_uint32_t *) (addr + 2); - *p = (((((*p >> 2) & MASK20) + value) & MASK20) << 2) | (*p & ~(MASK20 << 2)); + p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2); + p->val = (((((p->val >> 2) & MASK20) + value) & MASK20) << 2) | (p->val & ~(MASK20 << 2)); break; case 1: - p = (grub_uint32_t *) ((grub_uint8_t *) addr + 7); - *p = (((((*p >> 3) & MASK20) + value) & MASK20) << 3) | (*p & ~(MASK20 << 3)); + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7); + p->val = (((((p->val >> 3) & MASK20) + value) & MASK20) << 3) | (p->val & ~(MASK20 << 3)); break; case 2: - p = (grub_uint32_t *) ((grub_uint8_t *) addr + 12); - *p = (((((*p >> 4) & MASK20) + value) & MASK20) << 4) | (*p & ~(MASK20 << 4)); + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12); + p->val = (((((p->val >> 4) & MASK20) + value) & MASK20) << 4) | (p->val & ~(MASK20 << 4)); + break; + } +} + +#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) ) + +static grub_uint32_t +add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value) +{ + grub_uint32_t high, mid, low, c; + low = (a & 0x00007f); + mid = (a & 0x7fc000) >> 7; + high = (a & 0x003e00) << 5; + c = (low | mid | high) + value; + return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 5) & 0x003e00); +} + +static void +add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value) +{ + struct unaligned_uint32 *p; + switch (addr & 3) + { + case 0: + p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2); + p->val = ((add_value_to_slot_21_real (((p->val >> 2) & MASKF21), value) & MASKF21) << 2) | (p->val & ~(MASKF21 << 2)); + break; + case 1: + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7); + p->val = ((add_value_to_slot_21_real (((p->val >> 3) & MASKF21), value) & MASKF21) << 3) | (p->val & ~(MASKF21 << 3)); + break; + case 2: + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12); + p->val = ((add_value_to_slot_21_real (((p->val >> 4) & MASKF21), value) & MASKF21) << 4) | (p->val & ~(MASKF21 << 4)); break; } } @@ -147,8 +186,8 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; rel < max; rel++) - if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) - cnt++; + if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) + cnt++; } return cnt * sizeof (struct ia64_trampoline); @@ -165,7 +204,7 @@ grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr) for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); i < e->e_shnum; i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_REL) + if (s->sh_type == SHT_RELA) { grub_dl_segment_t seg; @@ -176,16 +215,18 @@ grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr) if (seg) { - Elf_Rel *rel, *max; + Elf_Rela *rel, *max; - for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), + for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; rel < max; rel++) switch (ELF_R_TYPE (rel->r_info)) { + case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: + case R_IA64_GPREL22: gp_size += 8; break; default: break; @@ -243,29 +284,22 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Rela *rel, *max; struct ia64_trampoline *tr; + tr = (void *) ((char *) seg->addr + ALIGN_UP (seg->size, GRUB_ARCH_DL_TRAMP_ALIGN)); + for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; rel < max; rel++) { - Elf_Word *addr; + grub_addr_t addr; Elf_Sym *sym; grub_uint64_t value; - int slot = 0; if (seg->size < (rel->r_offset & ~3)) return grub_error (GRUB_ERR_BAD_MODULE, "reloc offset is out of the segment"); - tr = (void *) ((char *) seg->addr + ALIGN_UP (seg->size, GRUB_ARCH_DL_TRAMP_ALIGN)); - - if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) - { - addr = (Elf_Word *) ((char *) seg->addr + (rel->r_offset & ~3)); - slot = rel->r_offset & 3; - } - else - addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); + addr = (grub_addr_t) seg->addr + rel->r_offset; sym = (Elf_Sym *) ((char *) mod->symtab + entsize * ELF_R_SYM (rel->r_info)); @@ -278,21 +312,26 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) { grub_uint64_t noff; make_trampoline (tr, value); - noff = ((char *) tr - (char *) addr) >> 4; + noff = ((char *) tr - (char *) (addr & ~3)) >> 4; tr++; if (noff & ~MASK19) return grub_error (GRUB_ERR_BAD_OS, - "trampoline offset too big"); - add_value_to_slot13_20 (addr, noff, slot); + "trampoline offset too big (%lx)", noff); + add_value_to_slot_20b (addr, noff); } break; case R_IA64_SEGREL64LSB: *(grub_uint64_t *) addr += value - rel->r_offset; break; + case R_IA64_DIR64LSB: + *(grub_uint64_t *) addr += value; + break; + case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: + case R_IA64_GPREL22: *gpptr = value; - add_value_to_slot13_20 (addr, (gpptr - gp) * sizeof (grub_uint64_t), slot); + add_value_to_slot_21 (addr, (gpptr - gp) * sizeof (grub_uint64_t)); gpptr++; break; From f49157dfe52bc95640645080f228cccd69ff72a5 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 23:30:25 +0100 Subject: [PATCH 087/211] Restructure module loading and many fixes. Now normal.mod loads successfully --- grub-core/kern/dl.c | 83 +++++++++++++++++++----------- grub-core/kern/emu/full.c | 15 ++---- grub-core/kern/ia64/dl.c | 105 +++++++++++++------------------------- include/grub/dl.h | 22 +++----- 4 files changed, 99 insertions(+), 126 deletions(-) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 0ccdbe03b..787fcfad0 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -229,6 +229,46 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) { unsigned i; Elf_Shdr *s; + grub_size_t tsize = 0, talign = 1; +#ifdef __ia64__ + grub_size_t tramp; + grub_size_t got; +#endif + char *ptr; + + for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize)) + { + tsize += ALIGN_UP (s->sh_size, s->sh_addralign); + if (talign < s->sh_addralign) + talign = s->sh_addralign; + } + +#ifdef __ia64__ + grub_arch_dl_get_tramp_got_size (e, &tramp, &got); + tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN); + if (talign < GRUB_ARCH_DL_TRAMP_ALIGN) + talign = GRUB_ARCH_DL_TRAMP_ALIGN; + tsize += ALIGN_UP (got, GRUB_ARCH_DL_GOT_ALIGN); + if (talign < GRUB_ARCH_DL_GOT_ALIGN) + talign = GRUB_ARCH_DL_GOT_ALIGN; +#endif + +#ifdef GRUB_MACHINE_EMU + if (talign < 8192 * 16) + talign = 8192 * 16; + tsize = ALIGN_UP (tsize, 8192 * 16); +#endif + + mod->base = grub_memalign (talign, tsize); + if (!mod->base) + return grub_errno; + ptr = mod->base; + +#ifdef GRUB_MACHINE_EMU + mprotect (mod->base, tsize, PROT_READ | PROT_WRITE | PROT_EXEC); +#endif for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff); i < e->e_shnum; @@ -237,38 +277,18 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) if (s->sh_flags & SHF_ALLOC) { grub_dl_segment_t seg; - grub_size_t tramp_size = 0; - grub_size_t alsize, align; seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg)); if (! seg) return grub_errno; - alsize = s->sh_size; - align = s->sh_addralign; - tramp_size = grub_arch_dl_get_tramp_size (e, i); - if (tramp_size && align < GRUB_ARCH_DL_TRAMP_ALIGN) - { - align = GRUB_ARCH_DL_TRAMP_ALIGN; - alsize = ALIGN_UP (alsize, GRUB_ARCH_DL_TRAMP_ALIGN); - } - alsize += tramp_size; -#ifdef GRUB_MACHINE_EMU - if (align < 8192 * 16) - align = 8192 * 16; - alsize = ALIGN_UP (alsize, 8192 * 16); -#endif - - if (alsize) + if (s->sh_size) { void *addr; - addr = grub_memalign (align, alsize); - if (! addr) - { - grub_free (seg); - return grub_errno; - } + ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign); + addr = ptr; + ptr += s->sh_size; switch (s->sh_type) { @@ -281,10 +301,6 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) } seg->addr = addr; -#ifdef GRUB_MACHINE_EMU - if (s->sh_flags & SHF_EXECINSTR) - mprotect (addr, alsize, PROT_READ | PROT_WRITE | PROT_EXEC); -#endif } else seg->addr = 0; @@ -295,6 +311,14 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) mod->segment = seg; } } +#ifdef __ia64__ + ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); + mod->tramp = ptr; + ptr += tramp; + ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_GOT_ALIGN); + mod->got = ptr; + ptr += got; +#endif return GRUB_ERR_NONE; } @@ -371,7 +395,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) if (!desc) return grub_errno; desc[0] = (void *) sym->st_value; - desc[1] = mod->gp; + desc[1] = mod->base; if (grub_dl_register_symbol (name, (void *) desc, mod)) return grub_errno; sym->st_value = (grub_addr_t) desc; @@ -564,7 +588,6 @@ grub_dl_load_core (void *addr, grub_size_t size) if (grub_dl_resolve_name (mod, e) || grub_dl_resolve_dependencies (mod, e) || grub_dl_load_segments (mod, e) - || grub_arch_dl_allocate_gp (mod, e) || grub_dl_resolve_symbols (mod, e) || grub_arch_dl_relocate_symbols (mod, e)) { diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 67a125301..80edb991e 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -50,18 +50,11 @@ grub_emu_init (void) } #ifdef __ia64__ -grub_size_t -grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), - unsigned sec __attribute__ ((unused))) +void grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), + grub_size_t *tramp, grub_size_t *got) { - return ~(grub_size_t)0; -} - -grub_err_t -grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)), - const void *ehdr __attribute__ ((unused))) -{ - return GRUB_ERR_BAD_MODULE; + *tramp = 0; + *got = 0; } #endif diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 55b50ff69..9bbebcd2f 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -75,9 +75,9 @@ add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value) grub_uint32_t high, mid, low, c; low = (a & 0x00007f); mid = (a & 0x7fc000) >> 7; - high = (a & 0x003e00) << 5; + high = (a & 0x003e00) << 7; c = (low | mid | high) + value; - return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 5) & 0x003e00); + return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00 } static void @@ -138,7 +138,7 @@ static void make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr) { grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); - tr->addr_hi[0] = ((addr & 0xc00000) >> 18); + tr->addr_hi[0] = ((addr & 0xc00000) >> 16); tr->addr_hi[1] = (addr >> 24) & 0xff; tr->addr_hi[2] = (addr >> 32) & 0xff; tr->addr_hi[3] = (addr >> 40) & 0xff; @@ -152,11 +152,11 @@ make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr) grub_memcpy (tr->jump, jump, sizeof (tr->jump)); } -grub_size_t -grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) +void +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got) { const Elf_Ehdr *e = ehdr; - int cnt = 0; + grub_size_t cntt = 0, cntg = 0;; const Elf_Shdr *s; Elf_Word entsize; unsigned i; @@ -169,7 +169,7 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) break; if (i == e->e_shnum) - return 0; + return; entsize = s->sh_entsize; @@ -180,68 +180,25 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) { Elf_Rela *rel, *max; - if (s->sh_info != sec) - continue; - for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; rel < max; rel++) - if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) - cnt++; + switch (ELF_R_TYPE (rel->r_info)) + { + case R_IA64_PCREL21B: + cntt++; + break; + case R_IA64_LTOFF_FPTR22: + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + cntg++; + break; + } } - - return cnt * sizeof (struct ia64_trampoline); + *tramp = cntt * sizeof (struct ia64_trampoline); + *got = cntg * sizeof (grub_uint64_t); } -grub_err_t -grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr) -{ - grub_size_t gp_size = 0; - const Elf_Ehdr *e = ehdr; - const Elf_Shdr *s; - unsigned i; - - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_RELA) - { - grub_dl_segment_t seg; - - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) - { - Elf_Rela *rel, *max; - - for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) - switch (ELF_R_TYPE (rel->r_info)) - { - case R_IA64_LTOFF_FPTR22: - case R_IA64_LTOFF22X: - case R_IA64_LTOFF22: - case R_IA64_GPREL22: - gp_size += 8; - break; - default: break; - } - } - } - - if (gp_size > MASK19) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "gp too big"); - - mod->gp = grub_malloc (gp_size); - if (!mod->gp) - return grub_errno; - return GRUB_ERR_NONE; -} /* Relocate symbols. */ grub_err_t @@ -252,8 +209,11 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Word entsize; unsigned i; grub_uint64_t *gp, *gpptr; + struct ia64_trampoline *tr; - gp = gpptr = (grub_uint64_t *) mod->gp; + gp = (grub_uint64_t *) mod->base; + gpptr = (grub_uint64_t *) mod->got; + tr = mod->tramp; /* Find a symbol table. */ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); @@ -282,9 +242,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) if (seg) { Elf_Rela *rel, *max; - struct ia64_trampoline *tr; - - tr = (void *) ((char *) seg->addr + ALIGN_UP (seg->size, GRUB_ARCH_DL_TRAMP_ALIGN)); for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; @@ -306,6 +263,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) /* On the PPC the value does not have an explicit addend, add it. */ value = sym->st_value + rel->r_addend; + switch (ELF_R_TYPE (rel->r_info)) { case R_IA64_PCREL21B: @@ -323,15 +281,24 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) case R_IA64_SEGREL64LSB: *(grub_uint64_t *) addr += value - rel->r_offset; break; + case R_IA64_FPTR64LSB: case R_IA64_DIR64LSB: *(grub_uint64_t *) addr += value; break; + case R_IA64_PCREL64LSB: + *(grub_uint64_t *) addr += value - addr; + break; + case R_IA64_GPREL22: + add_value_to_slot_21 (addr, value - (grub_addr_t) gp); + break; + case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: - case R_IA64_GPREL22: *gpptr = value; - add_value_to_slot_21 (addr, (gpptr - gp) * sizeof (grub_uint64_t)); + if ((addr & 0xffff) == 0x4301) + grub_dprintf ("modules", "off = %lx\n", (grub_addr_t) gpptr - (grub_addr_t) gp); + add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp); gpptr++; break; diff --git a/include/grub/dl.h b/include/grub/dl.h index c43c30ca7..b57c3ae87 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -93,8 +93,10 @@ struct grub_dl grub_addr_t init; grub_addr_t fini; #ifdef __ia64__ - char *gp; + void *got; + void *tramp; #endif + void *base; struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -123,24 +125,12 @@ void grub_arch_dl_init_linker (void); #endif #ifdef __ia64__ -grub_size_t grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec); -grub_err_t grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr); +void grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); #define GRUB_ARCH_DL_TRAMP_ALIGN 16 -#else -static inline grub_size_t -grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), int sec __attribute__ ((unused))) -{ - return 0; -} -static inline grub_err_t -grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)), - const void *ehdr __attribute__ ((unused))) -{ - return GRUB_ERR_NONE; -} +#define GRUB_ARCH_DL_GOT_ALIGN 16 -#define GRUB_ARCH_DL_TRAMP_ALIGN 1 +#else #endif From 0a2b2cdc95d1a8677fec66df81d48db88a2546f7 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 3 Jan 2011 00:30:26 +0100 Subject: [PATCH 088/211] Fix autogen --- grub-core/Makefile.core.def | 37 +---------------------- grub-core/kern/emu/{cache.S => cache_s.S} | 0 2 files changed, 1 insertion(+), 36 deletions(-) rename grub-core/kern/emu/{cache.S => cache_s.S} (100%) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 8f988b0be..ff5bf7a30 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -173,7 +173,7 @@ kernel = { emu = disk/host.c; emu = gnulib/progname.c; emu = gnulib/error.c; - emu = kern/emu/cache.S; + emu = kern/emu/cache_s.S; emu = kern/emu/console.c; emu = kern/emu/getroot.c; emu = kern/emu/hostdisk.c; @@ -463,41 +463,6 @@ module = { enable = i386_multiboot; }; -module = { - name = lsacpi; - - common = commands/lsacpi.c; - - enable = efi; - enable = i386_pc; - enable = i386_coreboot; - enable = i386_multiboot; -}; - -module = { - name = lsefisystab; - - common = commands/efi/lsefisystab.c; - - enable = efi; -}; - -module = { - name = lssal; - - common = commands/efi/lssal.c; - - enable = efi; -}; - -module = { - name = lsefimmap; - - common = commands/efi/lsefimmap.c; - - enable = efi; -}; - module = { name = lsacpi; diff --git a/grub-core/kern/emu/cache.S b/grub-core/kern/emu/cache_s.S similarity index 100% rename from grub-core/kern/emu/cache.S rename to grub-core/kern/emu/cache_s.S From 5faa440cb00186819dd2af2fca42fe4f9eb4d608 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 3 Jan 2011 00:47:21 +0100 Subject: [PATCH 089/211] Discard several spurious differences from mainline --- grub-core/kern/dl.c | 25 ------------------------- grub-core/kern/main.c | 2 +- include/grub/dl.h | 4 ++-- 3 files changed, 3 insertions(+), 28 deletions(-) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 7727745e8..787fcfad0 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -611,31 +611,6 @@ grub_dl_load_core (void *addr, grub_size_t size) return mod; } -#ifdef __ia64__ -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 = (char *) 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); -} -#endif - /* Load a module from the file FILENAME. */ grub_dl_t grub_dl_load_file (const char *filename) diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 24593e3c0..3474ed3bb 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -159,7 +159,7 @@ static void grub_load_normal_mode (void) { /* Load the module. */ -// grub_dl_load ("normal"); + grub_dl_load ("normal"); /* Something went wrong. Print errors here to let user know why we're entering rescue mode. */ grub_print_error (); diff --git a/include/grub/dl.h b/include/grub/dl.h index fcf5bb620..a5e5c3332 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -34,9 +34,9 @@ #ifndef GRUB_MOD_INIT #define GRUB_MOD_INIT(name) \ static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ -void grub_##name##_init (grub_dl_t); \ +void grub_##name##_init (void); \ void \ -grub_##name##_init (grub_dl_t mod) { grub_mod_init (mod); } \ +grub_##name##_init (void) { grub_mod_init (0); } \ static void \ grub_mod_init (grub_dl_t mod __attribute__ ((unused))) #endif From 0718f66d12275a940f8cf882d24aec2a48f17f99 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Jan 2011 00:56:28 +0100 Subject: [PATCH 090/211] Discard a bunch of junk code --- grub-core/kern/dl.c | 20 +- grub-core/kern/main.c | 2 - grub-core/kern/mm.c | 2 +- include/grub/dl.h | 4 +- include/grub/ia64/efi/misc.h | 27 -- util/ia64/efi/elf2pe.c | 812 ---------------------------------- util/ia64/efi/grub-install.in | 233 ---------- util/ia64/efi/pe32.h | 237 ---------- 8 files changed, 10 insertions(+), 1327 deletions(-) delete mode 100644 include/grub/ia64/efi/misc.h delete mode 100644 util/ia64/efi/elf2pe.c delete mode 100644 util/ia64/efi/grub-install.in delete mode 100644 util/ia64/efi/pe32.h diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 787fcfad0..f871b81a1 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -402,14 +402,12 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) } #endif if (bind != STB_LOCAL) - { - if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) - return grub_errno; - } + if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + return grub_errno; if (grub_strcmp (name, "grub_mod_init") == 0) - mod->init = sym->st_value; + mod->init = (void (*) (grub_dl_t)) sym->st_value; else if (grub_strcmp (name, "grub_mod_fini") == 0) - mod->fini = sym->st_value; + mod->fini = (void (*) (void)) sym->st_value; break; case STT_SECTION: @@ -434,9 +432,7 @@ static void grub_dl_call_init (grub_dl_t mod) { if (mod->init) - { - ((void (*) (grub_dl_t)) mod->init) (mod); - } + (mod->init) (mod); } static grub_err_t @@ -599,7 +595,7 @@ grub_dl_load_core (void *addr, grub_size_t size) grub_dl_flush_cache (mod); grub_dprintf ("modules", "module name: %s\n", mod->name); - grub_dprintf ("modules", "init function: %" PRIxGRUB_ADDR "\n", mod->init); + grub_dprintf ("modules", "init function: %p\n", mod->init); grub_dl_call_init (mod); if (grub_dl_add (mod)) @@ -699,9 +695,7 @@ grub_dl_unload (grub_dl_t mod) return 0; if (mod->fini) - { - ((void (*) (void)) mod->fini) (); - } + (mod->fini) (); grub_dl_remove (mod); grub_dl_unregister_symbols (mod); diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 3474ed3bb..8b6c8a180 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -76,7 +76,6 @@ grub_modules_get_end (void) static void grub_load_modules (void) { -#if 0 auto int hook (struct grub_module_header *); int hook (struct grub_module_header *header) { @@ -95,7 +94,6 @@ grub_load_modules (void) } grub_module_iterate (hook); -#endif } static void diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c index bd489e22c..8d9b5db78 100644 --- a/grub-core/kern/mm.c +++ b/grub-core/kern/mm.c @@ -313,7 +313,7 @@ grub_memalign (grub_size_t align, grub_size_t size) case 1: /* Unload unneeded modules. */ -// grub_dl_unload_unneeded (); + grub_dl_unload_unneeded (); count++; goto again; diff --git a/include/grub/dl.h b/include/grub/dl.h index a5e5c3332..b45928a76 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -92,8 +92,8 @@ struct grub_dl grub_dl_dep_t dep; grub_dl_segment_t segment; Elf_Sym *symtab; - grub_addr_t init; - grub_addr_t fini; + void (*init) (struct grub_dl *mod); + void (*fini) (void); #ifdef __ia64__ void *got; void *tramp; diff --git a/include/grub/ia64/efi/misc.h b/include/grub/ia64/efi/misc.h deleted file mode 100644 index 4f9c69e32..000000000 --- a/include/grub/ia64/efi/misc.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -void EXPORT_FUNC (__ia64_trampoline) (void); -void EXPORT_FUNC (grub_init_modules) (void); - -void -grub_init_module (const char *name, - void (*init)(grub_dl_t), void (*fini)(void)); - -extern unsigned long EXPORT_VAR (__gp); - diff --git a/util/ia64/efi/elf2pe.c b/util/ia64/efi/elf2pe.c deleted file mode 100644 index 66d28bde8..000000000 --- a/util/ia64/efi/elf2pe.c +++ /dev/null @@ -1,812 +0,0 @@ -/* elf2pe.c - convert elf binary to PE/Coff. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -#include -#include -#include -#include -#include -#include - -#if defined(ELF2PE_I386) -#define USE_ELF32 -#define USE_PE32 -#define ELF_MACHINE EM_386 -#define EFI_MACHINE PE32_MACHINE_I386 -#elif defined(ELF2PE_IA64) -#define USE_ELF64 -#define USE_PE32PLUS -#define ELF_MACHINE EM_IA_64 -#define EFI_MACHINE PE32_MACHINE_IA64 -#else -#error "unknown architecture" -#endif - -#include "pe32.h" - -const char *filename; - -int -is_elf_header(uint8_t *buffer) -{ - return (buffer[EI_MAG0] == ELFMAG0 - && buffer[EI_MAG1] == ELFMAG1 - && buffer[EI_MAG2] == ELFMAG2 - && buffer[EI_MAG3] == ELFMAG3); -} - -#ifdef USE_ELF32 -typedef Elf32_Shdr Elf_Shdr; -typedef Elf32_Ehdr Elf_Ehdr; -typedef Elf32_Rel Elf_Rel; -typedef Elf32_Rela Elf_Rela; -typedef Elf32_Sym Elf_Sym; -#define ELFCLASS ELFCLASS32 -#define ELF_R_TYPE(r) ELF32_R_TYPE(r) -#define ELF_R_SYM(r) ELF32_R_SYM(r) -#else -typedef Elf64_Shdr Elf_Shdr; -typedef Elf64_Ehdr Elf_Ehdr; -typedef Elf64_Rel Elf_Rel; -typedef Elf64_Rela Elf_Rela; -typedef Elf64_Sym Elf_Sym; -#define ELFCLASS ELFCLASS64 -#define ELF_R_TYPE(r) ELF64_R_TYPE(r) -#define ELF_R_SYM(r) ELF64_R_SYM(r) -#endif - -#ifdef 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 --git a/util/ia64/efi/grub-install.in b/util/ia64/efi/grub-install.in deleted file mode 100644 index 63b0c9f6c..000000000 --- a/util/ia64/efi/grub-install.in +++ /dev/null @@ -1,233 +0,0 @@ -#! /bin/sh - -# Install GRUB on your EFI partition. -# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. -# -# GRUB is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# GRUB is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GRUB. If not, see . - - -# Initialize some variables. -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 -} - -# 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 --git a/util/ia64/efi/pe32.h b/util/ia64/efi/pe32.h deleted file mode 100644 index 391e70c26..000000000 --- a/util/ia64/efi/pe32.h +++ /dev/null @@ -1,237 +0,0 @@ -/* pe32.h - PE/Coff definitions. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -#ifdef USE_PE32PLUS -typedef uint64_t pe32_uintptr_t; -#else -typedef uint32_t pe32_uintptr_t; -#endif - -struct pe32_coff_header -{ - uint16_t machine; - uint16_t num_sections; - uint32_t time; - uint32_t symtab_offset; - uint32_t num_symbols; - uint16_t optional_header_size; - uint16_t characteristics; -}; - -#define PE32_MACHINE_I386 0x014c -#define PE32_MACHINE_IA64 0x0200 -#define PE32_MACHINE_EBC 0x0EBC -#define PE32_MACHINE_X64 0x8664 - -#define PE32_RELOCS_STRIPPED 0x0001 -#define PE32_EXECUTABLE_IMAGE 0x0002 -#define PE32_LINE_NUMS_STRIPPED 0x0004 -#define PE32_LOCAL_SYMS_STRIPPED 0x0008 -#define PE32_AGGRESSIVE_WS_TRIM 0x0010 -#define PE32_LARGE_ADDRESS_AWARE 0x0020 -#define PE32_16BIT_MACHINE 0x0040 -#define PE32_BYTES_REVERSED_LO 0x0080 -#define PE32_32BIT_MACHINE 0x0100 -#define PE32_DEBUG_STRIPPED 0x0200 -#define PE32_REMOVABLE_RUN_FROM_SWAP 0x0400 -#define PE32_SYSTEM 0x1000 -#define PE32_DLL 0x2000 -#define PE32_UP_SYSTEM_ONLY 0x4000 -#define PE32_BYTES_REVERSED_HI 0x8000 - -struct pe32_data_directory -{ - uint32_t rva; - uint32_t size; -}; - -struct pe32_optional_header -{ - uint16_t magic; - uint8_t major_linker_version; - uint8_t minor_linker_version; - uint32_t code_size; - uint32_t data_size; - uint32_t bss_size; - uint32_t entry_addr; - uint32_t code_base; - -#ifndef USE_PE32PLUS - uint32_t data_base; -#endif - - pe32_uintptr_t image_base; - uint32_t section_alignment; - uint32_t file_alignment; - uint16_t major_os_version; - uint16_t minor_os_version; - uint16_t major_image_version; - uint16_t minor_image_version; - uint16_t major_subsystem_version; - uint16_t minor_subsystem_version; - uint32_t reserved; - uint32_t image_size; - uint32_t header_size; - uint32_t checksum; - uint16_t subsystem; - uint16_t dll_characteristics; - pe32_uintptr_t stack_reserve_size; - pe32_uintptr_t stack_commit_size; - pe32_uintptr_t heap_reserve_size; - pe32_uintptr_t heap_commit_size; - uint32_t loader_flags; - uint32_t num_data_directories; - - /* Data directories. */ - struct pe32_data_directory export_table; - struct pe32_data_directory import_table; - struct pe32_data_directory resource_table; - struct pe32_data_directory exception_table; - struct pe32_data_directory certificate_table; - struct pe32_data_directory base_relocation_table; - struct pe32_data_directory debug; - struct pe32_data_directory architecture; - struct pe32_data_directory global_ptr; - struct pe32_data_directory tls_table; - struct pe32_data_directory load_config_table; - struct pe32_data_directory bound_import; - struct pe32_data_directory iat; - struct pe32_data_directory delay_import_descriptor; - struct pe32_data_directory com_runtime_header; - struct pe32_data_directory reserved_entry; -}; - -#define PE32_PE32_MAGIC 0x10b -#define PE32_PE64_MAGIC 0x20b - -#define PE32_SUBSYSTEM_EFI_APPLICATION 10 -#define PE32_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 -#define PE32_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 -#define PE32_SUBSYSTEM_EFI_EFI_ROM 13 - -#define PE32_NUM_DATA_DIRECTORIES 16 - -struct pe32_section_header -{ - char name[8]; - uint32_t virtual_size; - uint32_t virtual_address; - uint32_t raw_data_size; - uint32_t raw_data_offset; - uint32_t relocations_offset; - uint32_t line_numbers_offset; - uint16_t num_relocations; - uint16_t num_line_numbers; - uint32_t characteristics; -}; - -#define PE32_SCN_CNT_CODE 0x00000020 -#define PE32_SCN_CNT_INITIALIZED_DATA 0x00000040 -#define PE32_SCN_MEM_DISCARDABLE 0x02000000 -#define PE32_SCN_MEM_EXECUTE 0x20000000 -#define PE32_SCN_MEM_READ 0x40000000 -#define PE32_SCN_MEM_WRITE 0x80000000 - -struct pe32_dos_header -{ - uint16_t magic; // Magic number - uint16_t cblp; // Bytes on last page of file - uint16_t cp; // Pages in file - uint16_t crlc; // Relocations - uint16_t cparhdr; // Size of header in paragraphs - uint16_t minalloc; // Minimum extra paragraphs needed - uint16_t maxalloc; // Maximum extra paragraphs needed - uint16_t ss; // Initial (relative) SS value - uint16_t sp; // Initial SP value - uint16_t csum; // Checksum - uint16_t ip; // Initial IP value - uint16_t cs; // Initial (relative) CS value - uint16_t lfa_rlc; // File address of relocation table - uint16_t ov_no; // Overlay number - uint16_t res[4]; // Reserved words - uint16_t oem_id; // OEM identifier (for e_oeminfo) - uint16_t oem_info; // OEM information; e_oemid specific - uint16_t res2[10]; // Reserved words - uint32_t new_hdr_offset; - - uint16_t stub[0x20]; -}; - -struct pe32_nt_header -{ - /* This is always PE\0\0. */ - char signature[4]; - - /* The COFF file header. */ - struct pe32_coff_header coff_header; - - /* The Optional header. */ - struct pe32_optional_header optional_header; -}; - -struct pe32_base_relocation -{ - uint32_t page_rva; - uint32_t block_size; -}; - -struct pe32_fixup_block -{ - uint32_t page_rva; - uint32_t block_size; - uint16_t entries[0]; -}; - -#define PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset)) - -#define PE32_REL_BASED_ABSOLUTE 0 -#define PE32_REL_BASED_HIGHLOW 3 -#define PE32_REL_BASED_IA64_IMM64 9 -#define PE32_REL_BASED_DIR64 10 - -#define PE32_DEBUG_TYPE_CODEVIEW 2 -struct pe32_debug_directory_entry { - uint32_t characteristics; - uint32_t time; - uint16_t major_version; - uint16_t minor_version; - uint32_t type; - uint32_t data_size; - uint32_t rva; - uint32_t file_offset; -}; - -#define PE32_CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10" -struct pe32_debug_codeview_nb10_entry { - uint32_t signature; // "NB10" - uint32_t unknown[3]; - char filename[0]; /* Filename of .PDB */ -}; - - -#if 1 -#define pe32_check(name, x) extern char pe32_check_##name [x ? 1 : -1] -#ifdef USE_PE32PLUS -#define PE32_HEADER_SIZE 112 -#else -#define PE32_HEADER_SIZE 96 -#endif - -pe32_check(optional_header, sizeof (struct pe32_optional_header) == PE32_HEADER_SIZE + PE32_NUM_DATA_DIRECTORIES * 8); -#endif - From c18271ed0042a870b84476b6b20241e884ed5792 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 3 Jan 2011 02:28:14 +0100 Subject: [PATCH 091/211] Fix compilation errors --- grub-core/Makefile.am | 1 - grub-core/Makefile.core.def | 9 ++++++--- grub-core/kern/ia64/efi/init.c | 2 -- grub-core/kern/ia64/efi/startup.S | 13 +++++++++++++ grub-core/lib/efi/halt.c | 2 ++ grub-core/loader/ia64/efi/linux.c | 7 +++---- include/grub/efi/api.h | 2 +- include/grub/offsets.h | 6 ++++++ 8 files changed, 31 insertions(+), 11 deletions(-) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 5481d9ebb..df691a586 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -130,7 +130,6 @@ if COND_ia64_efi KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ia64/efi/misc.h endif if COND_mips_yeeloong diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index ff5bf7a30..4581b79cf 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -126,8 +126,8 @@ kernel = { x86_64_efi = kern/i386/efi/init.c; ia64_efi = kern/ia64/efi/startup.S; - ia64_efi = kern/ia64/trampoline.S; ia64_efi = kern/ia64/efi/init.c; + ia64_efi = kern/ia64/dl.c; i386_pc = kern/i386/pc/init.c; i386_pc = kern/i386/pc/mmap.c; @@ -575,7 +575,8 @@ module = { i386_pc = commands/acpihalt.c; i386_coreboot = commands/acpihalt.c; i386_multiboot = commands/acpihalt.c; - x86_efi = commands/acpihalt.c; + i386_efi = commands/acpihalt.c; + x86_64_efi = commands/acpihalt.c; i386_multiboot = lib/i386/halt.c; i386_coreboot = lib/i386/halt.c; i386_qemu = lib/i386/halt.c; @@ -1244,6 +1245,7 @@ module = { mips_yeeloong = mmap/mips/yeeloong/uppermem.c; enable = x86; + enable = ia64_efi; enable = mips_yeeloong; }; @@ -1435,7 +1437,8 @@ module = { module = { name = efi_uga; efi = video/efi_uga.c; - enable = efi; + enable = i386_efi; + enable = x86_64_efi; }; module = { diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c index 06d5f5095..13a81a66e 100644 --- a/grub-core/kern/ia64/efi/init.c +++ b/grub-core/kern/ia64/efi/init.c @@ -25,13 +25,11 @@ #include #include #include -#include void grub_machine_init (void) { grub_efi_init (); - grub_init_modules (); } void diff --git a/grub-core/kern/ia64/efi/startup.S b/grub-core/kern/ia64/efi/startup.S index 9ba6858d9..fcaf4e189 100644 --- a/grub-core/kern/ia64/efi/startup.S +++ b/grub-core/kern/ia64/efi/startup.S @@ -15,6 +15,10 @@ * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ +#include +#include +#include + .text .psr abi64 .psr lsb @@ -38,3 +42,12 @@ _start: br.ret.sptk.few rp .endp _start + + . = _start + GRUB_KERNEL_MACHINE_PREFIX +VARIABLE(grub_prefix) + /* to be filled by grub-mkimage */ + + /* + * Leave some breathing room for the prefix. + */ + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c index c19536897..5ebf2cd1d 100644 --- a/grub-core/lib/efi/halt.c +++ b/grub-core/lib/efi/halt.c @@ -28,7 +28,9 @@ void grub_halt (void) { grub_machine_fini (); +#ifndef __ia64__ grub_acpi_halt (); +#endif efi_call_4 (grub_efi_system_table->runtime_services->reset_system, GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL); diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c index d9b4c338b..b018e4549 100644 --- a/grub-core/loader/ia64/efi/linux.c +++ b/grub-core/loader/ia64/efi/linux.c @@ -30,7 +30,6 @@ #include #include #include -#include #define ALIGN_MIN (256*1024*1024) @@ -512,7 +511,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - file = grub_gzfile_open (argv[0], 1); + file = grub_file_open (argv[0]); if (! file) { grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); @@ -594,7 +593,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), goto fail; } - file = grub_gzfile_open (argv[0], 1); + file = grub_file_open (argv[0]); if (! file) goto fail; @@ -644,7 +643,7 @@ grub_cmd_payload (grub_command_t cmd __attribute__ ((unused)), goto fail; } - file = grub_gzfile_open (argv[0], 1); + file = grub_file_open (argv[0]); if (! file) goto fail; diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index cb6b1113b..ded03a1b3 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -1234,7 +1234,7 @@ struct grub_efi_block_io }; typedef struct grub_efi_block_io grub_efi_block_io_t; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 +#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) #define efi_call_0(func) func() #define efi_call_1(func, a) func(a) diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 817372b69..55b0f8fb8 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -117,6 +117,12 @@ /* End of the data section. */ #define GRUB_KERNEL_I386_EFI_PREFIX_END 0x50 +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_IA64_EFI_PREFIX 0x50 + +/* End of the data section. */ +#define GRUB_KERNEL_IA64_EFI_PREFIX_END 0xa0 + /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_X86_64_EFI_PREFIX 0x8 From bea33583891ad31f7673a377244defa4e393c8b7 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 3 Jan 2011 13:46:36 +0100 Subject: [PATCH 092/211] First handling of ia64-efi in grub-mkimage --- grub-core/Makefile.core.def | 4 ++-- include/grub/efi/pe32.h | 1 + util/grub-mkimage.c | 34 +++++++++++++++++++++++++++++---- util/grub-mkimagexx.c | 38 ++++++++++++++++++++++++++++--------- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 4581b79cf..c21c38763 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -24,8 +24,8 @@ kernel = { x86_64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment'; ia64_efi_cflags = '-fno-builtin -fpic -minline-int-divide-max-throughput'; - ia64_efi_ldflags = '-melf_64'; - ia64_efi_stripflags = '-R .note -R .comment -X'; + ia64_efi_ldflags = '-Wl,-r,-d'; + ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment'; i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200'; diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 81a1a5797..c3efa9b3d 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -64,6 +64,7 @@ struct grub_pe32_coff_header }; #define GRUB_PE32_MACHINE_I386 0x14c +#define GRUB_PE32_MACHINE_IA64 0x200 #define GRUB_PE32_MACHINE_X86_64 0x8664 #define GRUB_PE32_RELOCS_STRIPPED 0x0001 diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 53e867602..507a7a80d 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -86,6 +86,7 @@ struct image_target_desc grub_uint64_t link_addr; unsigned mod_gap, mod_align; grub_compression_t default_compression; + grub_uint16_t pe_target; }; struct image_target_desc image_targets[] = @@ -191,6 +192,8 @@ struct image_target_desc image_targets[] = GRUB_PE32_SECTION_ALIGNMENT), .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, + .pe_target = GRUB_PE32_MACHINE_I386, + .elf_target = EM_386, }, { .name = "i386-ieee1275", @@ -253,6 +256,8 @@ struct image_target_desc image_targets[] = GRUB_PE32_SECTION_ALIGNMENT), .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, + .pe_target = GRUB_PE32_MACHINE_X86_64, + .elf_target = EM_X86_64, }, { .name = "mipsel-yeeloong-flash", @@ -354,6 +359,30 @@ struct image_target_desc image_targets[] = .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR }, + { + .name = "ia64-efi", + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_IA64_EFI_PREFIX, + .prefix_end = GRUB_KERNEL_IA64_EFI_PREFIX_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT), + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .pe_target = GRUB_PE32_MACHINE_IA64, + .elf_target = EM_IA_64, + }, }; #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) @@ -927,10 +956,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], /* The COFF file header. */ c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE); - if (image_target->voidp_sizeof == 4) - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); - else - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); + c->machine = grub_host_to_target16 (image_target->pe_target); c->num_sections = grub_host_to_target16 (4); c->time = grub_host_to_target32 (time (0)); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index ce51f2fbc..20cbacf15 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -101,9 +101,9 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, else if (index >= num_sections) grub_util_error ("section %d does not exist", index); - sym->st_value = (grub_target_to_host32 (sym->st_value) + sym->st_value = (grub_target_to_host (sym->st_value) + section_addresses[index]); - grub_util_info ("locating %s at 0x%x", name, sym->st_value); + grub_util_info ("locating %s at 0x%x", name, sym->st_value, section_addresses[index]); if (! start_address) if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) @@ -200,7 +200,9 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? r->r_addend : 0; - if (image_target->voidp_sizeof == 4) + switch (image_target->elf_target) + { + case EM_386: switch (ELF_R_TYPE (info)) { case R_386_NONE: @@ -224,11 +226,12 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, *target, offset); break; default: - grub_util_error ("unknown relocation type %d", + grub_util_error ("unknown relocation type 0x%x", ELF_R_TYPE (info)); break; } - else + break; + case EM_X86_64: switch (ELF_R_TYPE (info)) { @@ -270,6 +273,20 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, ELF_R_TYPE (info)); break; } + break; + case EM_IA_64: + switch (ELF_R_TYPE (info)) + { + default: + grub_util_error ("unknown relocation type 0x%x", + ELF_R_TYPE (info)); + break; + } + break; + default: + grub_util_error ("unknown architecture type %d", + image_target->elf_target); + } } } } @@ -417,8 +434,9 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, info = grub_le_to_cpu32 (r->r_info); /* Necessary to relocate only absolute addresses. */ - if (image_target->voidp_sizeof == 4) + switch (image_target->elf_target) { + case EM_386: if (ELF_R_TYPE (info) == R_386_32) { Elf_Addr addr; @@ -431,9 +449,8 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, addr, 0, current_address, image_target); } - } - else - { + break; + case EM_X86_64: if ((ELF_R_TYPE (info) == R_X86_64_32) || (ELF_R_TYPE (info) == R_X86_64_32S)) { @@ -452,6 +469,9 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, 0, current_address, image_target); } + break; + default: + grub_util_error ("unknown machine type 0x%x", image_target->elf_target); } } } From 7021cb3e16f4c5c32289ede7d0c53f4d4cc850c9 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 3 Jan 2011 13:48:33 +0100 Subject: [PATCH 093/211] Fix incorrect usage of variables in grub-install --- util/grub-install.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-install.in b/util/grub-install.in index b9e833360..716582dfd 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -648,7 +648,7 @@ elif [ x"$platform" = xefi ]; then efidir_disk="$(echo "$clean_devmap" | grep "^$(echo "$efidir_drive" | sed 's/,[^)]*//')" | cut -f2)" efidir_part="$(echo "$efidir_drive" | sed 's/^([^,]*,[^0-9]*//; s/[^0-9].*//')" efibootmgr $efi_quiet -c -d "$efidir_disk" -p "$efidir_part" -w \ - -L "$GRUB_DISTRIBUTOR" -l "\\EFI\\$efi_distributor\\$efi_file" + -L "$bootloader_id" -l "\\EFI\\$efi_distributor\\$efi_file" fi fi fi From 304e349b7fcfeaaa2a340c0adf30a281b82e62ff Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 5 Jan 2011 11:41:12 +0000 Subject: [PATCH 094/211] include for grub_find_device --- grub-core/kern/emu/hostdisk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 2a798a3cd..b21ac3285 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include From 6383772c926fb299953c8830b0d115b55c110f0d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 6 Jan 2011 18:08:01 +0000 Subject: [PATCH 095/211] remove unused variable --- grub-core/kern/emu/hostdisk.c | 1 - 1 file changed, 1 deletion(-) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index b21ac3285..ee3cc0a36 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1045,7 +1045,6 @@ grub_util_get_dm_node_linear_info (const char *dev, void *next = NULL; uint64_t length, start; char *target, *params; - const char *node_name; char *ptr; int major, minor; From 4b0782664739170dc3688a55e667a56146128e78 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 16:33:49 +0100 Subject: [PATCH 096/211] partitioned mdraid support (untested) --- grub-core/kern/emu/getroot.c | 2 +- grub-core/kern/emu/hostdisk.c | 15 ++++++++++----- include/grub/emu/misc.h | 2 ++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index a99bee9a4..0035c734a 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -639,7 +639,7 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) return GRUB_DEV_ABSTRACTION_LVM; /* Check for RAID. */ - if (!strncmp (os_dev, "/dev/md", 7)) + if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev)) return GRUB_DEV_ABSTRACTION_RAID; #endif diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index ee3cc0a36..eb84d0220 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -325,18 +325,23 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) return GRUB_ERR_NONE; } -#ifdef HAVE_DEVICE_MAPPER -static int -device_is_mapped (const char *dev) +int +grub_util_device_is_mapped (const char *dev) { +#ifdef HAVE_DEVICE_MAPPER struct stat st; + if (!grub_device_mapper_supported ()) + return 0; + if (stat (dev, &st) < 0) return 0; return dm_is_dm_major (major (st.st_rdev)); -} +#else + return 0; #endif /* HAVE_DEVICE_MAPPER */ +} #if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) static grub_disk_addr_t @@ -351,7 +356,7 @@ find_partition_start (const char *dev) # endif /* !defined(HAVE_DIOCGDINFO) */ # ifdef HAVE_DEVICE_MAPPER - if (grub_device_mapper_supported () && device_is_mapped (dev)) { + if (grub_util_device_is_mapped (dev)) { struct dm_task *task = NULL; grub_uint64_t start, length; char *target_type, *params, *space; diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index ef0d18300..03909e025 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -54,6 +54,8 @@ void grub_find_zpool_from_dir (const char *dir, char *grub_make_system_path_relative_to_its_root (const char *path) __attribute__ ((warn_unused_result)); +int +grub_util_device_is_mapped (const char *dev); void * EXPORT_FUNC(xmalloc) (grub_size_t size) __attribute__ ((warn_unused_result)); void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) __attribute__ ((warn_unused_result)); From f440c33fd2669b06a0c84cbbe1912054d5d39314 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Jan 2011 17:37:11 +0100 Subject: [PATCH 097/211] Make qemu-mips compile again. Still no grub-mkimage support --- configure.ac | 4 +-- gentpl.py | 8 ++--- grub-core/Makefile.am | 5 +++ grub-core/Makefile.core.def | 12 ++++--- grub-core/kern/mips/cache_flush.S | 4 +++ grub-core/kern/mips/qemu-mips/init.c | 3 +- grub-core/loader/mips/linux.c | 7 ++++- grub-core/loader/multiboot_mbi2.c | 2 ++ include/grub/mips/qemu_mips/cmos.h | 28 +++++++++++++++++ .../mips/{qemu-mips => qemu_mips}/kernel.h | 1 - .../mips/{qemu-mips => qemu_mips}/loader.h | 0 .../mips/{qemu-mips => qemu_mips}/memory.h | 31 +++++++++++++++++-- .../mips/{qemu-mips => qemu_mips}/serial.h | 0 .../grub/mips/{qemu-mips => qemu_mips}/time.h | 0 include/grub/offsets.h | 28 +++++++++++++---- 15 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 include/grub/mips/qemu_mips/cmos.h rename include/grub/mips/{qemu-mips => qemu_mips}/kernel.h (97%) rename include/grub/mips/{qemu-mips => qemu_mips}/loader.h (100%) rename include/grub/mips/{qemu-mips => qemu_mips}/memory.h (69%) rename include/grub/mips/{qemu-mips => qemu_mips}/serial.h (100%) rename include/grub/mips/{qemu-mips => qemu_mips}/time.h (100%) diff --git a/configure.ac b/configure.ac index 0b9207ea2..aac93fba2 100644 --- a/configure.ac +++ b/configure.ac @@ -122,7 +122,7 @@ case "$target_cpu"-"$platform" in i386-qemu) ;; powerpc-ieee1275) ;; sparc64-ieee1275) ;; - mips-qemu-mips) ;; + mips-qemu_mips) ;; mips-yeeloong) ;; *-emu) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; @@ -157,7 +157,7 @@ case "$platform" in pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;; emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; yeeloong) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; - qemu-mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; + qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1" ;; esac case "$target_cpu" in mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;; diff --git a/gentpl.py b/gentpl.py index a42a60667..97eff9f57 100644 --- a/gentpl.py +++ b/gentpl.py @@ -6,7 +6,7 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275", "x86_64_efi", - "mips_yeeloong", "sparc64_ieee1275", + "mips_yeeloong", "mips_qemu_mips", "sparc64_ieee1275", "powerpc_ieee1275" ] GROUPS = {} @@ -17,7 +17,7 @@ GROUPS["common"] = GRUB_PLATFORMS[:] GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ] GROUPS["x86_64"] = [ "x86_64_efi" ] GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] -GROUPS["mips"] = [ "mips_yeeloong" ] +GROUPS["mips"] = [ "mips_yeeloong", "mips_qemu_mips" ] GROUPS["sparc64"] = [ "sparc64_ieee1275" ] GROUPS["powerpc"] = [ "powerpc_ieee1275" ] @@ -29,8 +29,8 @@ GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") # Groups based on hardware features -GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_yeeloong"]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi") -GROUPS["pci"] = GROUPS["x86"] + GROUPS["mips"] +GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_yeeloong", "mips_qemu_mips" ]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi") +GROUPS["pci"] = GROUPS["x86"] + ["mips_yeeloong"] GROUPS["usb"] = GROUPS["pci"] # If gfxterm is main output console integrate it into kernel diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 94f7f3ffe..65f638745 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -145,6 +145,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h endif +if COND_mips_qemu_mips +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +endif + if COND_powerpc_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2cca4fa95..1cc832892 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -48,7 +48,7 @@ kernel = { i386_ieee1275_startup = kern/i386/ieee1275/startup.S; i386_coreboot_startup = kern/i386/coreboot/startup.S; i386_multiboot_startup = kern/i386/coreboot/startup.S; - mips_yeeloong_startup = kern/mips/startup.S; + mips_startup = kern/mips/startup.S; sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; @@ -82,6 +82,7 @@ kernel = { i386_coreboot = kern/generic/rtc_get_time_ms.c; i386_multiboot = kern/generic/rtc_get_time_ms.c; mips_yeeloong = kern/generic/rtc_get_time_ms.c; + mips_qemu_mips = kern/generic/rtc_get_time_ms.c; ieee1275 = disk/ieee1275/ofdisk.c; ieee1275 = kern/ieee1275/cmain.c; @@ -140,10 +141,11 @@ kernel = { mips_yeeloong = bus/bonito.c; mips_yeeloong = bus/cs5536.c; mips_yeeloong = bus/pci.c; - mips_yeeloong = kern/mips/cache.S; - mips_yeeloong = kern/mips/dl.c; - mips_yeeloong = kern/mips/init.c; + mips = kern/mips/cache.S; + mips = kern/mips/dl.c; + mips = kern/mips/init.c; mips_yeeloong = kern/mips/yeeloong/init.c; + mips_qemu_mips = kern/mips/qemu-mips/init.c; mips_yeeloong = term/at_keyboard.c; mips_yeeloong = term/serial.c; mips_yeeloong = video/sm712.c; @@ -1229,7 +1231,7 @@ module = { mips_yeeloong = mmap/mips/yeeloong/uppermem.c; enable = x86; - enable = mips_yeeloong; + enable = mips; }; module = { diff --git a/grub-core/kern/mips/cache_flush.S b/grub-core/kern/mips/cache_flush.S index 11096c035..87a738caa 100644 --- a/grub-core/kern/mips/cache_flush.S +++ b/grub-core/kern/mips/cache_flush.S @@ -1,3 +1,6 @@ + + /* Qemu doesn't emulate caches. Oh boy. */ +#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS move $t2, $a0 addu $t3, $a0, $a1 srl $t2, $t2, 5 @@ -21,3 +24,4 @@ bne $t1, $zero, 2b addiu $t0, $t0, 0x1 sync +#endif \ No newline at end of file diff --git a/grub-core/kern/mips/qemu-mips/init.c b/grub-core/kern/mips/qemu-mips/init.c index f2bb652a8..1690b5451 100644 --- a/grub-core/kern/mips/qemu-mips/init.c +++ b/grub-core/kern/mips/qemu-mips/init.c @@ -6,9 +6,8 @@ #include #include #include -#include #include -#include +#include #define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264)) diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 6ae2a9321..8520609ed 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -29,8 +29,10 @@ #include /* For frequencies. */ +#ifdef GRUB_MACHINE_MIPS_YEELOONG #include #include +#endif #ifdef GRUB_MACHINE_MIPS_YEELOONG /* This can be detected on runtime from PMON, but: @@ -314,6 +316,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_envp = extra; envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground; linux_envs = (char *) (linux_envp + 5); +#ifdef GRUB_MACHINE_MIPS_YEELOONG grub_snprintf (linux_envs, sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), "memsize=%lld", (unsigned long long) grub_mmap_get_lower () >> 20); @@ -338,8 +341,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + target_addr; linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); - linux_envp[4] = 0; +#else + linux_envp[0] = 0; +#endif grub_loader_set (grub_linux_boot, grub_linux_unload, 1); initrd_loaded = 0; diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index 3141f0028..e4a630d03 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -671,6 +671,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } +#if defined (__i386) || defined (__x86_64__) || defined (GRUB_MACHINE_MIPS_YEELOONG) { struct multiboot_tag_basic_meminfo *tag = (struct multiboot_tag_basic_meminfo *) ptrorig; @@ -682,6 +683,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->mem_upper = grub_mmap_get_upper () / 1024; ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } +#endif if (bootdev_set) { diff --git a/include/grub/mips/qemu_mips/cmos.h b/include/grub/mips/qemu_mips/cmos.h new file mode 100644 index 000000000..4aef40e81 --- /dev/null +++ b/include/grub/mips/qemu_mips/cmos.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_CMOS_H +#define GRUB_CPU_CMOS_H 1 + +#include +#include + +#define GRUB_CMOS_ADDR_REG 0xb4000070 +#define GRUB_CMOS_DATA_REG 0xb4000071 + +#endif /* GRUB_CPU_CMOS_H */ diff --git a/include/grub/mips/qemu-mips/kernel.h b/include/grub/mips/qemu_mips/kernel.h similarity index 97% rename from include/grub/mips/qemu-mips/kernel.h rename to include/grub/mips/qemu_mips/kernel.h index 230455dbf..c08405e83 100644 --- a/include/grub/mips/qemu-mips/kernel.h +++ b/include/grub/mips/qemu_mips/kernel.h @@ -20,7 +20,6 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include -#include #ifndef ASM_FILE diff --git a/include/grub/mips/qemu-mips/loader.h b/include/grub/mips/qemu_mips/loader.h similarity index 100% rename from include/grub/mips/qemu-mips/loader.h rename to include/grub/mips/qemu_mips/loader.h diff --git a/include/grub/mips/qemu-mips/memory.h b/include/grub/mips/qemu_mips/memory.h similarity index 69% rename from include/grub/mips/qemu-mips/memory.h rename to include/grub/mips/qemu_mips/memory.h index 99d9ef2be..57220a1e2 100644 --- a/include/grub/mips/qemu-mips/memory.h +++ b/include/grub/mips/qemu_mips/memory.h @@ -28,11 +28,37 @@ #define GRUB_MACHINE_MEMORY_STACK_HIGH 0x80f00000 #define GRUB_MACHINE_MEMORY_USABLE 0x81000000 +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 +#define GRUB_MACHINE_MEMORY_MAX_TYPE 1 + /* This one is special: it's used internally but is never reported + by firmware. */ +#define GRUB_MACHINE_MEMORY_HOLE 2 +#define GRUB_MACHINE_MEMORY_RESERVED GRUB_MACHINE_MEMORY_HOLE + #ifndef ASM_FILE + +typedef grub_addr_t grub_phys_addr_t; + +static inline grub_phys_addr_t +grub_vtop (void *a) +{ + return ((grub_phys_addr_t) a) & 0x1fffffff; +} + +static inline void * +grub_map_memory (grub_phys_addr_t a, grub_size_t size __attribute__ ((unused))) +{ + return (void *) (a | 0x80000000); +} + +static inline void +grub_unmap_memory (void *a __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ +} + grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate) (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); -grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) - (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); static inline grub_err_t grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), @@ -47,6 +73,7 @@ grub_machine_mmap_unregister (int handle __attribute__ ((unused))) { return GRUB_ERR_NONE; } + #endif #endif diff --git a/include/grub/mips/qemu-mips/serial.h b/include/grub/mips/qemu_mips/serial.h similarity index 100% rename from include/grub/mips/qemu-mips/serial.h rename to include/grub/mips/qemu_mips/serial.h diff --git a/include/grub/mips/qemu-mips/time.h b/include/grub/mips/qemu_mips/time.h similarity index 100% rename from include/grub/mips/qemu-mips/time.h rename to include/grub/mips/qemu_mips/time.h diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 817372b69..fa609b16f 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -104,12 +104,26 @@ #define GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN 32 -#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE 0xc +#define GRUB_KERNEL_MIPS_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_MIPS_UNCOMPRESSED_SIZE 0xc -#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE 0x08 -#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX 0x0c -#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END 0x54 +#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE GRUB_KERNEL_MIPS_COMPRESSED_SIZE +#define GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE GRUB_KERNEL_MIPS_UNCOMPRESSED_SIZE + +#define GRUB_KERNEL_MIPS_QEMU_MIPS_COMPRESSED_SIZE GRUB_KERNEL_MIPS_COMPRESSED_SIZE +#define GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE GRUB_KERNEL_MIPS_UNCOMPRESSED_SIZE + +#define GRUB_KERNEL_MIPS_TOTAL_MODULE_SIZE 0x08 +#define GRUB_KERNEL_MIPS_PREFIX 0x0c +#define GRUB_KERNEL_MIPS_PREFIX_END 0x54 + +#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE GRUB_KERNEL_MIPS_TOTAL_MODULE_SIZE +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_PREFIX +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END GRUB_KERNEL_MIPS_PREFIX_END + +#define GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE GRUB_KERNEL_MIPS_TOTAL_MODULE_SIZE +#define GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX GRUB_KERNEL_MIPS_PREFIX +#define GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END GRUB_KERNEL_MIPS_PREFIX_END /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_EFI_PREFIX 0x8 @@ -144,7 +158,9 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 -#define GRUB_KERNEL_MIPS_YEELOONG_MOD_ALIGN 0x1 +#define GRUB_KERNEL_MIPS_MOD_ALIGN 0x1 +#define GRUB_KERNEL_MIPS_YEELOONG_MOD_ALIGN GRUB_KERNEL_MIPS_MOD_ALIGN +#define GRUB_KERNEL_MIPS_QEMU_MIPS_MOD_ALIGN GRUB_KERNEL_MIPS_MOD_ALIGN /* Minimal gap between _end and the start of the modules. It's a hack for PowerMac to prevent "CLAIM failed" error. The real fix is to From 01b08a0f15e12a1bcbea49b092a960645c9880fb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 Jan 2011 13:44:16 +0100 Subject: [PATCH 098/211] initial SIS315PRO support --- grub-core/Makefile.core.def | 1 + grub-core/kern/mips/yeeloong/init.c | 2 + grub-core/video/sis315pro.c | 246 ++++++++++++++++++++++++++++ include/grub/video.h | 3 +- 4 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 grub-core/video/sis315pro.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index ce7d0b0c2..a67c805c9 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -147,6 +147,7 @@ kernel = { mips_yeeloong = term/at_keyboard.c; mips_yeeloong = term/serial.c; mips_yeeloong = video/sm712.c; + mips_yeeloong = video/sis315pro.c; extra_dist = video/sm712_init.c; mips_yeeloong = commands/keylayouts.c; diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/yeeloong/init.c index 7a48d69f5..f42c9696d 100644 --- a/grub-core/kern/mips/yeeloong/init.c +++ b/grub-core/kern/mips/yeeloong/init.c @@ -33,6 +33,7 @@ #include extern void grub_video_sm712_init (void); +extern void grub_video_sis315pro_init (void); extern void grub_video_init (void); extern void grub_bitmap_init (void); extern void grub_font_init (void); @@ -202,6 +203,7 @@ grub_machine_init (void) relies on a working heap. */ grub_video_init (); grub_video_sm712_init (); + grub_video_sis315pro_init (); grub_bitmap_init (); grub_font_init (); grub_gfxterm_init (); diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c new file mode 100644 index 000000000..59ff6432d --- /dev/null +++ b/grub-core/video/sis315pro.c @@ -0,0 +1,246 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009,2010 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 . + */ + +#define grub_video_render_target grub_video_fbrender_target + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_SIS315PRO_PCIID 0x03251039 +#define GRUB_SIS315PRO_TOTAL_MEMORY_SPACE 0x800000 + +static struct +{ + struct grub_video_mode_info mode_info; + struct grub_video_render_target *render_target; + + grub_uint8_t *ptr; + int mapped; + grub_uint32_t base; + grub_pci_device_t dev; +} framebuffer; + +#ifndef TEST +static grub_err_t +grub_video_sis315pro_video_init (void) +{ + /* Reset frame buffer. */ + grub_memset (&framebuffer, 0, sizeof(framebuffer)); + + return grub_video_fb_init (); +} + +static grub_err_t +grub_video_sis315pro_video_fini (void) +{ + if (framebuffer.mapped) + grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, + GRUB_SIS315PRO_TOTAL_MEMORY_SPACE); + + return grub_video_fb_fini (); +} +#endif + +static grub_err_t +grub_video_sis315pro_setup (unsigned int width, unsigned int height, + unsigned int mode_type, + unsigned int mode_mask __attribute__ ((unused))) +{ + int depth; + grub_err_t err; + int found = 0; + +#ifndef TEST + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) + { + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA + || pciid != GRUB_SIS315PRO_PCIID) + return 0; + + found = 1; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + framebuffer.base = grub_pci_read (addr); + framebuffer.dev = dev; + + return 1; + } + + /* Decode depth from mode_type. If it is zero, then autodetect. */ + depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) + >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; + + if ((width != 640 && width != 0) || (height != 400 && height != 0) + || (depth != 8 && depth != 0)) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Only 640x400x8 is supported"); + + grub_pci_iterate (find_card); + if (!found) + return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); +#endif + /* Fill mode info details. */ + framebuffer.mode_info.width = 640; + framebuffer.mode_info.height = 400; + framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + framebuffer.mode_info.bpp = 8; + framebuffer.mode_info.bytes_per_pixel = 1; + framebuffer.mode_info.pitch = 640 * 1; + framebuffer.mode_info.number_of_colors = 256; + framebuffer.mode_info.red_mask_size = 0; + framebuffer.mode_info.red_field_pos = 0; + framebuffer.mode_info.green_mask_size = 0; + framebuffer.mode_info.green_field_pos = 0; + framebuffer.mode_info.blue_mask_size = 0; + framebuffer.mode_info.blue_field_pos = 0; + framebuffer.mode_info.reserved_mask_size = 0; + framebuffer.mode_info.reserved_field_pos = 0; +#ifndef TEST + framebuffer.mode_info.blit_format + = grub_video_get_blit_format (&framebuffer.mode_info); +#endif + + /* We can safely discard volatile attribute. */ +#ifndef TEST + framebuffer.ptr + = (void *) grub_pci_device_map_range (framebuffer.dev, + framebuffer.base, + GRUB_SIS315PRO_TOTAL_MEMORY_SPACE); +#endif + framebuffer.mapped = 1; + +#ifndef TEST + /* Prevent garbage from appearing on the screen. */ + grub_memset (framebuffer.ptr, 0, + framebuffer.mode_info.height * framebuffer.mode_info.pitch); +#endif + +#ifndef TEST + err = grub_video_fb_create_render_target_from_pointer (&framebuffer + .render_target, + &framebuffer.mode_info, + framebuffer.ptr); + + if (err) + return err; + + err = grub_video_fb_set_active_render_target (framebuffer.render_target); + + if (err) + return err; + + /* Copy default palette to initialize emulated palette. */ + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); +#endif + return err; +} + +#ifndef TEST + +static grub_err_t +grub_video_sis315pro_swap_buffers (void) +{ + /* TODO: Implement buffer swapping. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_sis315pro_set_active_render_target (struct grub_video_render_target *target) +{ + if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) + target = framebuffer.render_target; + + return grub_video_fb_set_active_render_target (target); +} + +static grub_err_t +grub_video_sis315pro_get_info_and_fini (struct grub_video_mode_info *mode_info, + void **framebuf) +{ + grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); + *framebuf = (char *) framebuffer.ptr; + + grub_video_fb_fini (); + + return GRUB_ERR_NONE; +} + +static struct grub_video_adapter grub_video_sis315pro_adapter = + { + .name = "SIS315PRO Video Driver", + .id = GRUB_VIDEO_DRIVER_SIS315PRO, + + .prio = GRUB_VIDEO_ADAPTER_PRIO_NATIVE, + + .init = grub_video_sis315pro_video_init, + .fini = grub_video_sis315pro_video_fini, + .setup = grub_video_sis315pro_setup, + .get_info = grub_video_fb_get_info, + .get_info_and_fini = grub_video_sis315pro_get_info_and_fini, + .set_palette = grub_video_fb_set_palette, + .get_palette = grub_video_fb_get_palette, + .set_viewport = grub_video_fb_set_viewport, + .get_viewport = grub_video_fb_get_viewport, + .map_color = grub_video_fb_map_color, + .map_rgb = grub_video_fb_map_rgb, + .map_rgba = grub_video_fb_map_rgba, + .unmap_color = grub_video_fb_unmap_color, + .fill_rect = grub_video_fb_fill_rect, + .blit_bitmap = grub_video_fb_blit_bitmap, + .blit_render_target = grub_video_fb_blit_render_target, + .scroll = grub_video_fb_scroll, + .swap_buffers = grub_video_sis315pro_swap_buffers, + .create_render_target = grub_video_fb_create_render_target, + .delete_render_target = grub_video_fb_delete_render_target, + .set_active_render_target = grub_video_sis315pro_set_active_render_target, + .get_active_render_target = grub_video_fb_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(video_sis315pro) +{ + grub_video_register (&grub_video_sis315pro_adapter); +} + +GRUB_MOD_FINI(video_sis315pro) +{ + grub_video_unregister (&grub_video_sis315pro_adapter); +} +#else +int +main () +{ + grub_video_sis315pro_setup (640, 400, 0, 0); +} +#endif diff --git a/include/grub/video.h b/include/grub/video.h index 5350d87eb..8773199c2 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -211,7 +211,8 @@ typedef enum grub_video_driver_id GRUB_VIDEO_DRIVER_VGA, GRUB_VIDEO_DRIVER_CIRRUS, GRUB_VIDEO_DRIVER_BOCHS, - GRUB_VIDEO_DRIVER_SDL + GRUB_VIDEO_DRIVER_SDL, + GRUB_VIDEO_DRIVER_SIS315PRO, } grub_video_driver_id_t; typedef enum grub_video_adapter_prio From edf9d1f7ebb6c37e2de52c50268331384a6e66b5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 Jan 2011 14:00:55 +0100 Subject: [PATCH 099/211] Don't double the divisor on Geode UART, it runs at normal speed --- grub-core/term/ns8250.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c index 4be528df8..5d403c845 100644 --- a/grub-core/term/ns8250.c +++ b/grub-core/term/ns8250.c @@ -37,7 +37,8 @@ static const grub_port_t serial_hw_io_addr[] = GRUB_MACHINE_SERIAL_PORTS; /* Convert speed to divisor. */ static unsigned short -serial_get_divisor (unsigned int speed) +serial_get_divisor (const struct grub_serial_port *port, + const struct grub_serial_config *config) { unsigned int i; @@ -63,13 +64,16 @@ serial_get_divisor (unsigned int speed) /* Set the baud rate. */ for (i = 0; i < ARRAY_SIZE (divisor_tab); i++) - if (divisor_tab[i].speed == speed) - /* UART in Yeeloong runs twice the usual rate. */ + if (divisor_tab[i].speed == config->speed) + { + /* internal UART in Yeeloong runs twice the usual rate. */ #ifdef GRUB_MACHINE_MIPS_YEELOONG - return 2 * divisor_tab[i].div; -#else - return divisor_tab[i].div; + if (port->port == 0xbff003f8) + return 2 * divisor_tab[i].div; + else #endif + return divisor_tab[i].div; + } return 0; } @@ -93,7 +97,7 @@ do_real_config (struct grub_serial_port *port) port->broken = 0; - divisor = serial_get_divisor (port->config.speed); + divisor = serial_get_divisor (port, &port->config); /* Turn off the interrupt. */ grub_outb (0, port->port + UART_IER); @@ -188,7 +192,7 @@ serial_hw_configure (struct grub_serial_port *port, { unsigned short divisor; - divisor = serial_get_divisor (config->speed); + divisor = serial_get_divisor (port, config); if (divisor == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed"); From 74eea126f472abc82268d937a26d7367e75e9369 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 Jan 2011 15:28:44 +0100 Subject: [PATCH 100/211] fuloong support --- grub-core/boot/mips/yeeloong/fwstart.S | 3 ++ grub-core/kern/mips/startup.S | 3 ++ grub-core/kern/mips/yeeloong/init.c | 7 +++-- grub-core/loader/mips/linux.c | 40 +++++++++++++++----------- grub-core/term/serial.c | 16 ++++++++--- include/grub/mips/yeeloong/kernel.h | 5 ++++ include/grub/mips/yeeloong/serial.h | 9 ++++-- include/grub/term.h | 16 +++++++++++ 8 files changed, 74 insertions(+), 25 deletions(-) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 425458401..4c2fe5543 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -25,6 +25,9 @@ #include #include +#define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT0 +#define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT0_DIVISOR_115200 + .set noreorder .set noat .set nomacro diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index ae0e0b187..4bf4c1762 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -20,6 +20,7 @@ #include #include #include +#include #include #define BASE_ADDR 8 @@ -59,6 +60,8 @@ VARIABLE (grub_arch_memsize) .long 0 VARIABLE (grub_arch_highmemsize) .long 0 +VARIABLE (grub_arch_machine) + .long GRUB_ARCH_MACHINE_FULOONG #endif cont: /* Save our base. */ diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/yeeloong/init.c index f42c9696d..6787a205d 100644 --- a/grub-core/kern/mips/yeeloong/init.c +++ b/grub-core/kern/mips/yeeloong/init.c @@ -208,8 +208,11 @@ grub_machine_init (void) grub_font_init (); grub_gfxterm_init (); - grub_keylayouts_init (); - grub_at_keyboard_init (); + if (grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG) + { + grub_keylayouts_init (); + grub_at_keyboard_init (); + } grub_terminfo_init (); grub_serial_init (); diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 6ae2a9321..244d2b8a3 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -33,11 +33,13 @@ #include #ifdef GRUB_MACHINE_MIPS_YEELOONG -/* This can be detected on runtime from PMON, but: - a) it wouldn't work when GRUB is the firmware - and - b) for now we only support Yeeloong anyway. */ -#define LOONGSON_MACHTYPE "machtype=lemote-yeeloong-2f-8.9inches" +#include + +const char loongson_machtypes[][60] = + { + [GRUB_ARCH_MACHINE_YEELOONG] = "machtype=lemote-yeeloong-2f-8.9inches", + [GRUB_ARCH_MACHINE_FULOONG] = "machtype=lemote-fuloong-2f-unknown" + }; #endif static grub_dl_t my_mod; @@ -222,7 +224,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* For arguments. */ linux_argc = argc; -#ifdef LOONGSON_MACHTYPE +#ifdef GRUB_MACHINE_MIPS_YEELOONG linux_argc++; #endif /* Main arguments. */ @@ -237,8 +239,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* Normal arguments. */ for (i = 1; i < argc; i++) size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); -#ifdef LOONGSON_MACHTYPE - size += ALIGN_UP (sizeof (LOONGSON_MACHTYPE), 4); +#ifdef GRUB_MACHINE_MIPS_YEELOONG + size += ALIGN_UP (sizeof (loongson_machtypes[0]), 4); #endif /* rd arguments. */ @@ -277,14 +279,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_argv++; linux_args += ALIGN_UP (sizeof ("a0"), 4); -#ifdef LOONGSON_MACHTYPE - /* In Loongson platform, it is the responsibility of the bootloader/firmware - to supply the OS kernel with machine type information. */ - grub_memcpy (linux_args, LOONGSON_MACHTYPE, sizeof (LOONGSON_MACHTYPE)); - *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground - + target_addr; - linux_argv++; - linux_args += ALIGN_UP (sizeof (LOONGSON_MACHTYPE), 4); +#ifdef GRUB_MACHINE_MIPS_YEELOONG + { + unsigned mtype = grub_arch_machine; + if (mtype >= ARRAY_SIZE (loongson_machtypes)) + mtype = 0; + /* In Loongson platform, it is the responsibility of the bootloader/firmware + to supply the OS kernel with machine type information. */ + grub_memcpy (linux_args, loongson_machtypes[mtype], + sizeof (loongson_machtypes[mtype])); + *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground + + target_addr; + linux_argv++; + linux_args += ALIGN_UP (sizeof (loongson_machtypes[mtype]), 4); + } #endif for (i = 1; i < argc; i++) diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index e672a89d6..aca5769fd 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -26,6 +26,9 @@ #include #include #include +#ifdef GRUB_MACHINE_MIPS_YEELOONG +#include +#endif #define FOR_SERIAL_PORTS(var) FOR_LIST_ELEMENTS((var), (grub_serial_ports)) @@ -296,17 +299,22 @@ grub_serial_register (struct grub_serial_port *port) port->term_out = out; grub_terminfo_output_register (out, "vt100"); #ifdef GRUB_MACHINE_MIPS_YEELOONG - if (grub_strcmp (port->name, "com0") == 0) + if (grub_strcmp (port->name, + (grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG) + ? "com0" : "com2") == 0) { grub_term_register_input_active ("serial_*", in); grub_term_register_output_active ("serial_*", out); } else -#endif { - grub_term_register_input ("serial_*", in); - grub_term_register_output ("serial_*", out); + grub_term_register_input_inactive ("serial_*", in); + grub_term_register_output_inactive ("serial_*", out); } +#else + grub_term_register_input ("serial_*", in); + grub_term_register_output ("serial_*", out); +#endif return GRUB_ERR_NONE; } diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h index 15cf9f9fd..857b37a15 100644 --- a/include/grub/mips/yeeloong/kernel.h +++ b/include/grub/mips/yeeloong/kernel.h @@ -21,11 +21,16 @@ #include +#define GRUB_ARCH_MACHINE_YEELOONG 0 +#define GRUB_ARCH_MACHINE_FULOONG 1 + #ifndef ASM_FILE void EXPORT_FUNC (grub_reboot) (void) __attribute__ ((noreturn)); void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); +extern grub_uint32_t EXPORT_VAR (grub_arch_machine); + #endif #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/yeeloong/serial.h b/include/grub/mips/yeeloong/serial.h index ebe3638a1..45e6d8457 100644 --- a/include/grub/mips/yeeloong/serial.h +++ b/include/grub/mips/yeeloong/serial.h @@ -19,11 +19,14 @@ #ifndef GRUB_MACHINE_SERIAL_HEADER #define GRUB_MACHINE_SERIAL_HEADER 1 -#define GRUB_MACHINE_SERIAL_DIVISOR_115200 2 -#define GRUB_MACHINE_SERIAL_PORT 0xbff003f8 +#define GRUB_MACHINE_SERIAL_PORT0_DIVISOR_115200 2 +#define GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200 1 +#define GRUB_MACHINE_SERIAL_PORT0 0xbff003f8 +#define GRUB_MACHINE_SERIAL_PORT1 0xbfd003f8 +#define GRUB_MACHINE_SERIAL_PORT2 0xbfd002f8 #ifndef ASM_FILE -#define GRUB_MACHINE_SERIAL_PORTS { GRUB_MACHINE_SERIAL_PORT } +#define GRUB_MACHINE_SERIAL_PORTS { GRUB_MACHINE_SERIAL_PORT0, GRUB_MACHINE_SERIAL_PORT1, GRUB_MACHINE_SERIAL_PORT2 } #else #endif diff --git a/include/grub/term.h b/include/grub/term.h index dbcb2f52c..e9efc3f84 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -251,6 +251,14 @@ grub_term_register_input (const char *name __attribute__ ((unused)), } } +static inline void +grub_term_register_input_inactive (const char *name __attribute__ ((unused)), + grub_term_input_t term) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), + GRUB_AS_LIST (term)); +} + static inline void grub_term_register_input_active (const char *name __attribute__ ((unused)), grub_term_input_t term) @@ -275,6 +283,14 @@ grub_term_register_output (const char *name __attribute__ ((unused)), } } +static inline void +grub_term_register_output_inactive (const char *name __attribute__ ((unused)), + grub_term_output_t term) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), + GRUB_AS_LIST (term)); +} + static inline void grub_term_register_output_active (const char *name __attribute__ ((unused)), grub_term_output_t term) From 8f49d04c98338c29bddeb1f407500f954a78494e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 Jan 2011 19:04:27 +0100 Subject: [PATCH 101/211] machtype autodetection --- grub-core/boot/mips/startup_raw.S | 56 ++++++++++++++++++++++++-- grub-core/boot/mips/yeeloong/fwstart.S | 3 +- grub-core/kern/mips/startup.S | 1 + 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index c41ce8257..d8789982f 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -20,6 +20,7 @@ #include #include #include +#include #include #define BASE_ADDR 8 @@ -54,10 +55,12 @@ codestart: move $s3, $zero move $s4, $zero move $s5, $zero + move $s7, $zero /* $a2 has the environment. */ - addiu $t0, $a2, 1 - beq $t0, $zero, argdone + addiu $t0, $zero, -0x10 + and $t1, $a2, $t0 + beq $t0, $t1, argfw nop move $t0, $a2 argcont: @@ -72,11 +75,19 @@ argcont: nop ;\ b 2f;\ move reg, $v0; \ -1: +1: +#define DO_CHECKT1(str, val) \ + move $t6, $t1 ;\ + addiu $t7, $s0, (str - base);\ + bal do_check ;\ + li $t2, val + DO_PARSE (busclockstr, $s2) DO_PARSE (cpuclockstr, $s3) DO_PARSE (memsizestr, $s4) DO_PARSE (highmemsizestr, $s5) + DO_CHECKT1 (pmon_yeeloong_verstr, GRUB_ARCH_MACHINE_YEELOONG) + DO_CHECKT1 (pmon_fuloong_verstr, GRUB_ARCH_MACHINE_FULOONG) 2: b argcont addiu $t0, $t0, 4 @@ -120,8 +131,47 @@ busclockstr: .asciiz "busclock=" cpuclockstr: .asciiz "cpuclock=" memsizestr: .asciiz "memsize=" highmemsizestr: .asciiz "highmemsize=" +machtype_yeeloong_str1: .asciiz "machtype=8.9" +machtype_yeeloong_str2: .asciiz "machtype=lemote-yeeloong-" +machtype_fuloong_str: .asciiz "machtype=lemote-fuloong-" +pmon_yeeloong_str: .asciiz "PMON_VER=LM8" +pmon_fuloong_str: .asciiz "PMON_VER=LM6" +pmon_yeeloong_verstr: .asciiz "Version=LM8" +pmon_fuloong_verstr: .asciiz "Version=LM6" .p2align 2 + argdone: + beq $a0, $zero, cmdlinedone + nop +#define DO_CHECKA1(str, val) \ + lw $t6, 0($a1) ;\ + addiu $t7, $s0, (str - base);\ + bal do_check ;\ + li $t2, val + DO_CHECKA1 (machtype_yeeloong_str1, GRUB_ARCH_MACHINE_YEELOONG) + DO_CHECKA1 (machtype_yeeloong_str2, GRUB_ARCH_MACHINE_YEELOONG) + DO_CHECKA1 (pmon_yeeloong_str, GRUB_ARCH_MACHINE_YEELOONG) + DO_CHECKA1 (machtype_fuloong_str, GRUB_ARCH_MACHINE_FULOONG) + DO_CHECKA1 (pmon_fuloong_str, GRUB_ARCH_MACHINE_FULOONG) + addiu $a0, $a0, -1 + b argdone + addiu $a1, $a1, 4 +do_check: + lb $t4, 0($t7) + beq $t4, $zero, 1f + lb $t3, 0($t6) + bne $t3, $t4, 2f + addiu $t6, $t6, 1 + b do_check + addiu $t7, $t7, 1 +1: + move $s7, $t2 +2: + jr $ra + nop +argfw: + not $s7, $a2 +cmdlinedone: #endif /* Copy the decompressor. */ lui $t1, %hi(base) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 4c2fe5543..bc59c1174 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -629,6 +630,6 @@ continue: lui $t0, %hi(cached_continue - 0x20000000) addiu $t0, $t0, %lo(cached_continue - 0x20000000) jr $t0 - addiu $a2, $zero, -1 + addiu $a2, $zero, -(1 + GRUB_ARCH_MACHINE_YEELOONG) cached_continue: \ No newline at end of file diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 4bf4c1762..999beee79 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -74,6 +74,7 @@ cont: sw $s3, 4($t1) sw $s4, 8($t1) sw $s5, 12($t1) + sw $s7, 16($t1) #endif /* Move the modules out of BSS. */ From cfe6539cfe8146ea27ec30fa1ecf55f95b331601 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 Jan 2011 19:05:12 +0100 Subject: [PATCH 102/211] initialise keylayout on fuloong too --- grub-core/kern/mips/yeeloong/init.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/yeeloong/init.c index 6787a205d..b444caf06 100644 --- a/grub-core/kern/mips/yeeloong/init.c +++ b/grub-core/kern/mips/yeeloong/init.c @@ -208,11 +208,9 @@ grub_machine_init (void) grub_font_init (); grub_gfxterm_init (); + grub_keylayouts_init (); if (grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG) - { - grub_keylayouts_init (); - grub_at_keyboard_init (); - } + grub_at_keyboard_init (); grub_terminfo_init (); grub_serial_init (); From 99388e0cf8e7c3e8f3bdf3d828caddade7b68613 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 Jan 2011 19:39:12 +0100 Subject: [PATCH 103/211] Fuloong shutdown support --- grub-core/kern/mips/yeeloong/init.c | 26 ++++++++++++++++++++++---- include/grub/mips/loongson.h | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/yeeloong/init.c index b444caf06..7526111cc 100644 --- a/grub-core/kern/mips/yeeloong/init.c +++ b/grub-core/kern/mips/yeeloong/init.c @@ -226,10 +226,28 @@ grub_machine_fini (void) void grub_halt (void) { - grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG) - & ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG); - - grub_millisleep (1500); + switch (grub_arch_machine) + { + case GRUB_ARCH_MACHINE_FULOONG: + { + grub_pci_device_t dev; + grub_port_t p; + if (grub_cs5536_find (&dev)) + { + p = (grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_GPIO_BAR) + & GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE; + grub_outl ((1 << 13), p + 4); + grub_outl ((1 << 29), p); + grub_millisleep (5000); + } + } + break; + case GRUB_ARCH_MACHINE_YEELOONG: + grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG) + & ~GRUB_CPU_YEELOONG_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG); + grub_millisleep (1500); + break; + } grub_printf ("Shutdown failed\n"); grub_refresh (); diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h index 6cb1178d5..e9f1583ab 100644 --- a/include/grub/mips/loongson.h +++ b/include/grub/mips/loongson.h @@ -85,6 +85,6 @@ #define GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI 0xbfe00154 #define GRUB_CPU_LOONGSON_GPIOCFG 0xbfe00120 -#define GRUB_CPU_LOONGSON_SHUTDOWN_GPIO 1 +#define GRUB_CPU_YEELOONG_SHUTDOWN_GPIO 1 #endif From ea9e017dc5064da8a8f8d336785bd1937d1b6737 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Jan 2011 21:50:09 +0100 Subject: [PATCH 104/211] Correct address to unsupported memory type string --- grub-core/boot/mips/yeeloong/fwstart.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index bc59c1174..560e0ed8c 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -124,7 +124,7 @@ __start: ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 lui $a0, %hi(unimplemented_memory_type) bne $t0, $v0, fatal - addiu $a0, $a0, %hi(unimplemented_memory_type) + addiu $a0, $a0, %lo(unimplemented_memory_type) /* And here is our goal: DDR2 controller initialisation. */ lui $t0, %hi(GRUB_CPU_LOONGSON_CORECFG) From 9b4ad415e649d02565d429d539c7800df967b2b6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Jan 2011 21:52:43 +0100 Subject: [PATCH 105/211] Retry the scan for CS5536 in case of failure --- grub-core/boot/mips/yeeloong/fwstart.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 560e0ed8c..144c76ac6 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -43,17 +43,18 @@ __start: /* $t4 chooses device in priority encoding. */ /* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG. This way we don't need to sacrifice a register for it. */ +retry_cs5536: /* We have only one bus (0). Function is 0. */ lui $t0, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE) lui $t3, %hi(GRUB_CS5536_PCIID) addiu $t3, $t3, %lo(GRUB_CS5536_PCIID) ori $t4, $zero, 1 - lui $a0, %hi(no_cs5536) 1: andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1) - beql $t4, $zero, fatal - addiu $a0, $a0, %lo(no_cs5536) + /* In case of failure try again. CS5536 may be slow to come up. */ + beql $t4, $zero, retry_cs5536 + nop sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0) lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_PCI_ID) ($t1) bnel $t2, $t3, 1b @@ -383,7 +384,6 @@ read_spd_fail: ori $v0, $v0, 0x100 notification_string: .asciz "GRUB " -no_cs5536: .asciz "No CS5536 found.\n\r" cs5536_found: .asciz "CS5536 at " sm_failed: .asciz "SM transaction failed.\n\r" unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r" From 0889c3401c4b2c2c9359fdfe06a7169f8b9b4bc4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Jan 2011 21:56:00 +0100 Subject: [PATCH 106/211] Explicitly enable MSR mailbox --- grub-core/boot/mips/yeeloong/fwstart.S | 4 ++++ include/grub/cs5536.h | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 144c76ac6..184aff5d2 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -66,6 +66,10 @@ retry_cs5536: move $a0, $t4 /* Initialise SMBus controller. */ + lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE) + li $t1, GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED + sw $t1, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_CONFIG) ($t0) + /* Set GPIO LBAR. */ lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR) addiu $a0, $a0, %lo(GRUB_CS5536_MSR_GPIO_BAR) diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index cd17e11fc..de0d6df7e 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -26,9 +26,11 @@ #endif #define GRUB_CS5536_PCIID 0x208f1022 -#define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4 -#define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8 -#define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc +#define GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED 0x1 +#define GRUB_CS5536_MSR_MAILBOX_CONFIG 0xf0 +#define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4 +#define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8 +#define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc #define GRUB_CS5536_MSR_IRQ_MAP_BAR 0x80000008 #define GRUB_CS5536_MSR_SMB_BAR 0x8000000b From 1ccfc5d20139637a65ab81bb3c606e122eb341f4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Jan 2011 00:38:30 +0100 Subject: [PATCH 107/211] Move GPIO init to fwstart.S for convenience --- grub-core/boot/mips/yeeloong/fwstart.S | 70 ++++++++++++++++++++++---- grub-core/bus/cs5536.c | 31 ------------ 2 files changed, 61 insertions(+), 40 deletions(-) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 184aff5d2..41559ffa4 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -65,7 +65,6 @@ retry_cs5536: bal printhex move $a0, $t4 - /* Initialise SMBus controller. */ lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE) li $t1, GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED sw $t1, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_CONFIG) ($t0) @@ -79,6 +78,10 @@ retry_cs5536: ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \ | GRUB_CS5536_LBAR_ENABLE) >> 32) + bal gpio_init + nop + + /* Initialise SMBus controller. */ /* Set SMBUS LBAR. */ lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR) addiu $a0, $a0, %lo(GRUB_CS5536_MSR_SMB_BAR) @@ -92,14 +95,6 @@ retry_cs5536: bal message addiu $a0, $a0, %lo(smbus_enabled) - /* Enable SMBus controller pins. */ - lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO) - ori $t1, $zero, GRUB_GPIO_SMBUS_PINS - sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_EN) ($t0) - sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_AUX1) ($t0) - sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_EN) ($t0) - sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_AUX1) ($t0) - lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS) /* Disable SMB. */ @@ -215,6 +210,24 @@ other_exception: b fatal addiu $a0, $a0, %lo(unhandled_exception) +gpio_init: + lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO) + addiu $t0, $t0, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO) + lui $t1, %hi (gpio_dump) + addiu $t1, $t1, %lo (gpio_dump) + +1: + lw $t2, 0($t1) + sw $t2, 0($t0) + addiu $t0, $t0, 4 + addiu $t1, $t1, 4 + lui $t2, %hi (gpio_dump_end) + addiu $t2, $t2, %lo (gpio_dump_end) + bne $t1, $t2, 1b + nop + jr $ra + nop + /* Same as similarly named C function but in asm since we need it early. */ /* In: none. Out: none. Clobbered: $t0, $t1, $a0. */ @@ -434,6 +447,45 @@ regdump: .quad 0 /* 1b */ .quad 0 /* 1c */ +/* Dump of GPIO connections. FIXME: Remove useless and macroify. */ +gpio_dump: +#ifdef FULOONG + .long 0xffff0000, 0x2eefd110, 0xffff0000, 0xffff0000 + .long 0x2eefd110, 0xffff0000, 0x1000efff, 0xefff1000 + .long 0x3df3c20c, 0xffff0000, 0xffff0000, 0xffff0000 + .long 0x7df3820c, 0x3df3c20c, 0xffff0000, 0x00000000 + .long 0xffff0000, 0xffff0000, 0x3de3c21c, 0x3d83c27c + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000 + .long 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000 + .long 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000 + .long 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000 + .long 0xffff0000, 0xffff0000, 0xefff1000, 0xefff1000 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 +#else + .long 0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000 + .long 0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000 + .long 0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000 + .long 0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000 + .long 0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000 + .long 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000 + .long 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000 + .long 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000 + .long 0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 + .long 0x00000000, 0x50000000, 0x00000000, 0x00000000 +#endif +gpio_dump_end: + .p2align write_dumpreg: diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c index 088f4dfc1..690b8f29a 100644 --- a/grub-core/bus/cs5536.c +++ b/grub-core/bus/cs5536.c @@ -213,26 +213,6 @@ grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, return GRUB_ERR_NONE; } -/* Dump of GPIO connections. FIXME: Remove useless and macroify. */ -static grub_uint32_t gpiodump[] = { - 0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000, - 0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000, - 0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000, - 0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000, - 0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, - 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000, - 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000, - 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000, - 0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x50000000, 0x00000000, 0x00000000, -}; - static inline void set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start, grub_uint16_t len) @@ -273,17 +253,6 @@ set_p2d (grub_pci_device_t dev, int num, int dest, grub_uint32_t start) void grub_cs5536_init_geode (grub_pci_device_t dev) { - int i; - - /* Make sure GPIO is where we expect it to be. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GPIO_BAR, - GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_GPIO); - - /* Setup GPIO. */ - for (i = 0; i < (int) ARRAY_SIZE (gpiodump); i++) - ((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_IO_BASE - + GRUB_CS5536_LBAR_GPIO)) [i] = gpiodump[i]; - /* Enable more BARs. */ grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR, GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_IRQ_MAP); From 5ea788ada075c32a171390c26d06e596eefd2412 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Jan 2011 00:40:03 +0100 Subject: [PATCH 108/211] Geode UART2 (for Fuloong) fwstart.img support --- grub-core/boot/mips/yeeloong/fwstart.S | 42 +++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 41559ffa4..1a1a44c85 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -26,8 +26,13 @@ #include #include +#ifdef FULOONG +#define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT2 +#define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200 +#else #define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT0 #define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT0_DIVISOR_115200 +#endif .set noreorder .set noat @@ -37,8 +42,14 @@ start: _start: __start: + /* Put serial init as soon as possible. But on Fuloong serial is past + Geode, so on Fuloong we need Geode first. + */ +#ifndef FULOONG bal serial_hw_init nop +#endif + /* Find CS5536 controller. */ /* $t4 chooses device in priority encoding. */ /* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG. @@ -60,10 +71,12 @@ retry_cs5536: bnel $t2, $t3, 1b sll $t4, $t4, 1 +#ifndef FULOONG bal message addiu $a0, $a0, %lo(cs5536_found) bal printhex move $a0, $t4 +#endif lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE) li $t1, GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED @@ -81,6 +94,11 @@ retry_cs5536: bal gpio_init nop +#ifdef FULOONG + bal serial_hw_init + nop +#endif + /* Initialise SMBus controller. */ /* Set SMBUS LBAR. */ lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR) @@ -230,8 +248,29 @@ gpio_init: /* Same as similarly named C function but in asm since we need it early. */ - /* In: none. Out: none. Clobbered: $t0, $t1, $a0. */ + /* In: none. Out: none. Clobbered: $t0, $t1, $t2, $a0, $a1, $a2. */ serial_hw_init: + move $t2, $ra +#ifdef FULOONG + lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_LEG_IO) + addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_LEG_IO) + li $a1, 0x04570003 + bal wrmsr + move $a2, $zero + + lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_UART1_CONF) + addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_UART1_CONF) + li $a1, 2 + bal wrmsr + move $a2, $zero + + lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_UART2_CONF) + addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_UART2_CONF) + li $a1, 2 + bal wrmsr + move $a2, $zero +#endif + lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) /* Turn off the interrupt. */ @@ -261,6 +300,7 @@ serial_hw_init: /* Let message return to original caller. */ lui $a0, %hi(notification_string) addiu $a0, $a0, %lo(notification_string) + move $ra, $t2 /* Print message on serial console. */ /* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */ From c69ef8a0ab622769bc7ede5c45b36a38e2203035 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Jan 2011 00:40:59 +0100 Subject: [PATCH 109/211] pass machine type from fwstart.S. Minor cleanup --- grub-core/boot/mips/yeeloong/fwstart.S | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 1a1a44c85..8c0963ba3 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -726,6 +726,10 @@ continue: lui $t0, %hi(cached_continue - 0x20000000) addiu $t0, $t0, %lo(cached_continue - 0x20000000) jr $t0 +#ifdef FULOONG + addiu $a2, $zero, -(1 + GRUB_ARCH_MACHINE_FULOONG) +#else addiu $a2, $zero, -(1 + GRUB_ARCH_MACHINE_YEELOONG) +#endif -cached_continue: \ No newline at end of file +cached_continue: From 9f7322f50e80df1cd67ffda5bbd148b6bcefcd80 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Jan 2011 00:47:36 +0100 Subject: [PATCH 110/211] Add missing UART2 definitions --- include/grub/cs5536.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index de0d6df7e..90a39df44 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -80,6 +80,8 @@ #define GRUB_CS5536_DIVIL_LPC_INTERRUPTS 0x1002 #define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL 0x8000004e #define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE 0x80 +#define GRUB_CS5536_MSR_DIVIL_UART1_CONF 0x8000003a +#define GRUB_CS5536_MSR_DIVIL_UART2_CONF 0x8000003e #define GRUB_CS5536_MSR_USB_OHCI_BASE 0x40000008 #define GRUB_CS5536_MSR_USB_EHCI_BASE 0x40000009 From 44626c910ec2a8a4ebea96b590a549610301735b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Jan 2011 01:45:11 +0100 Subject: [PATCH 111/211] Add fuloong registers for RAM controller --- grub-core/boot/mips/yeeloong/fwstart.S | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 8c0963ba3..995aa5071 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -465,14 +465,22 @@ regdump: .quad 0x0100020200010101 /* 4 */ .quad 0x0a04030603050203 /* 6 */ .quad 0x0f0e040000010a0b /* 7 */ +#ifdef FULOONG + .quad 0x0000000100000001 /* 8 */ +#else .quad 0x0000010200000102 /* 8 */ +#endif .quad 0x0000060c00000000 /* 9 */ .quad 0x2323233f3f1f0200 /* a */ .quad 0x5f7f232323232323 /* b */ .quad 0x002a3c0615000000 /* c */ .quad 0x002a002a002a002a /* d */ .quad 0x002a002a002a002a /* e */ +#ifdef FULOONG + .quad 0x00b40020005b0004 /* f */ +#else .quad 0x00b40020006d0004 /* f */ +#endif .quad 0x070007ff00000087 /* 10 */ .quad 0x000000000016101f /* 11 */ .quad 0x001c000000000000 /* 12 */ From 88906eaa69c3f117ef7416b225c33f6bdaf7a2c4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Jan 2011 01:46:00 +0100 Subject: [PATCH 112/211] Fix accidental disable of Geode UARTs --- grub-core/boot/mips/yeeloong/fwstart.S | 7 ++++++- grub-core/bus/cs5536.c | 25 ++++++++++++++++++++----- include/grub/cs5536.h | 2 ++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 995aa5071..d25ff1a5b 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -254,7 +254,12 @@ serial_hw_init: #ifdef FULOONG lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_LEG_IO) addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_LEG_IO) - li $a1, 0x04570003 + li $a1, (GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3 \ + | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP \ + | GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 \ + | GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1 \ + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 \ + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1) bal wrmsr move $a2, $zero diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c index 690b8f29a..f5b2089e3 100644 --- a/grub-core/bus/cs5536.c +++ b/grub-core/bus/cs5536.c @@ -21,6 +21,7 @@ #include #include #include +#include int grub_cs5536_find (grub_pci_device_t *devp) @@ -264,11 +265,25 @@ grub_cs5536_init_geode (grub_pci_device_t dev) GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM); /* Setup DIVIL. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO, - GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP - | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); + switch (grub_arch_machine) + { + case GRUB_ARCH_MACHINE_YEELOONG: + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO, + GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); + break; + case GRUB_ARCH_MACHINE_FULOONG: + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO, + GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); + break; + } grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK, (~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff); grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK, diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index 90a39df44..103b30633 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -75,6 +75,8 @@ #define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1 0x00000002 #define GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 0x10000000 #define GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP 0x04000000 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1 0x00070000 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3 0x00500000 #define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK 0x80000024 #define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK 0x80000025 #define GRUB_CS5536_DIVIL_LPC_INTERRUPTS 0x1002 From dc1c21edb7be8bd892204981c31cd496f65e9a35 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Jan 2011 01:49:25 +0100 Subject: [PATCH 113/211] Add informative #define --- grub-core/boot/mips/yeeloong/fwstart.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index d25ff1a5b..41ed0063b 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -26,6 +26,8 @@ #include #include +/* #define FULOONG 1 */ + #ifdef FULOONG #define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT2 #define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200 From a9fa2a22d7f7e8f696c6cbca6103f3a62528c3a8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Jan 2011 02:20:04 +0100 Subject: [PATCH 114/211] Integrate Fuloong firmware port into build system and grub-mkimage --- grub-core/Makefile.core.def | 8 ++ grub-core/boot/mips/yeeloong/fuloong.S | 2 + grub-core/boot/mips/yeeloong/fwstart.S | 2 - util/grub-mkimage.c | 144 +++++++++++++++++-------- 4 files changed, 108 insertions(+), 48 deletions(-) create mode 100644 grub-core/boot/mips/yeeloong/fuloong.S diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index a67c805c9..e651e1596 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -329,6 +329,14 @@ image = { enable = mips_yeeloong; }; +image = { + name = fwstart_fuloong; + mips_yeeloong = boot/mips/yeeloong/fuloong.S; + objcopyflags = '-O binary'; + ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; + enable = mips_yeeloong; +}; + module = { name = trig; common_nodist = trigtables.c; diff --git a/grub-core/boot/mips/yeeloong/fuloong.S b/grub-core/boot/mips/yeeloong/fuloong.S new file mode 100644 index 000000000..5df0d54c1 --- /dev/null +++ b/grub-core/boot/mips/yeeloong/fuloong.S @@ -0,0 +1,2 @@ +#define FULOONG 1 +#include "fwstart.S" diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 41ed0063b..d25ff1a5b 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -26,8 +26,6 @@ #include #include -/* #define FULOONG 1 */ - #ifdef FULOONG #define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT2 #define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200 diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 0375d3ed5..663e60f08 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -58,14 +58,15 @@ typedef enum { struct image_target_desc { - const char *name; + const char *dirname; + const char *names[6]; grub_size_t voidp_sizeof; int bigendian; enum { IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, - IMAGE_I386_PC_PXE + IMAGE_FULOONG_FLASH, IMAGE_I386_PC_PXE } id; enum { @@ -92,7 +93,8 @@ struct image_target_desc struct image_target_desc image_targets[] = { { - .name = "i386-coreboot", + .dirname = "i386-coreboot", + .names = { "i386-coreboot", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_COREBOOT, @@ -114,7 +116,8 @@ struct image_target_desc image_targets[] = .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN }, { - .name = "i386-multiboot", + .dirname = "i386-multiboot", + .names = { "i386-multiboot", NULL}, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_COREBOOT, @@ -136,7 +139,8 @@ struct image_target_desc image_targets[] = .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN }, { - .name = "i386-pc", + .dirname = "i386-pc", + .names = { "i386-pc", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_I386_PC, @@ -154,7 +158,8 @@ struct image_target_desc image_targets[] = .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, { - .name = "i386-pc-pxe", + .dirname = "i386-pc", + .names = { "i386-pc-pxe", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_I386_PC_PXE, @@ -172,7 +177,8 @@ struct image_target_desc image_targets[] = .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, { - .name = "i386-efi", + .dirname = "i386-efi", + .names = { "i386-efi", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_EFI, @@ -194,7 +200,8 @@ struct image_target_desc image_targets[] = .install_bsd_part = TARGET_NO_FIELD, }, { - .name = "i386-ieee1275", + .dirname = "i386-ieee1275", + .names = { "i386-ieee1275", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_I386_IEEE1275, @@ -216,7 +223,8 @@ struct image_target_desc image_targets[] = .link_align = 4, }, { - .name = "i386-qemu", + .dirname = "i386-qemu", + .names = { "i386-qemu", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_QEMU, @@ -234,7 +242,8 @@ struct image_target_desc image_targets[] = .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR }, { - .name = "x86_64-efi", + .dirname = "x86_64-efi", + .names = { "x86_64-efi", NULL }, .voidp_sizeof = 8, .bigendian = 0, .id = IMAGE_EFI, @@ -256,7 +265,8 @@ struct image_target_desc image_targets[] = .install_bsd_part = TARGET_NO_FIELD, }, { - .name = "mipsel-yeeloong-flash", + .dirname = "mipsel-yeeloong", + .names = { "mipsel-yeeloong-flash", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_YEELOONG_FLASH, @@ -277,7 +287,31 @@ struct image_target_desc image_targets[] = .default_compression = COMPRESSION_NONE }, { - .name = "mipsel-yeeloong-elf", + .dirname = "mipsel-yeeloong", + .names = { "mipsel-fuloong-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_FULOONG_FLASH, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, + .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, + .raw_size = 0, + .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, + .compressed_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN, + .default_compression = COMPRESSION_NONE + }, + { + .dirname = "mipsel-yeeloong", + .names = { "mipsel-loongson-elf", "mipsel-yeeloong-elf", + "mipsel-fuloong-elf", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_YEELOONG_ELF, @@ -298,7 +332,8 @@ struct image_target_desc image_targets[] = .default_compression = COMPRESSION_NONE }, { - .name = "powerpc-ieee1275", + .dirname = "powerpc-ieee1275", + .names = { "powerpc-ieee1275", NULL }, .voidp_sizeof = 4, .bigendian = 1, .id = IMAGE_PPC, @@ -320,7 +355,8 @@ struct image_target_desc image_targets[] = .link_align = 4 }, { - .name = "sparc64-ieee1275-raw", + .dirname = "sparc64-ieee1275", + .names = { "sparc64-ieee1275-raw", NULL }, .voidp_sizeof = 8, .bigendian = 1, .id = IMAGE_SPARC64_RAW, @@ -338,7 +374,8 @@ struct image_target_desc image_targets[] = .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR }, { - .name = "sparc64-ieee1275-aout", + .dirname = "sparc64-ieee1275", + .names = { "sparc64-ieee1275-aout", NULL }, .voidp_sizeof = 8, .bigendian = 1, .id = IMAGE_SPARC64_AOUT, @@ -1163,6 +1200,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], } break; case IMAGE_YEELOONG_FLASH: + case IMAGE_FULOONG_FLASH: { char *rom_img; size_t rom_size; @@ -1170,20 +1208,40 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t boot_size; grub_uint8_t context[GRUB_MD_SHA512->contextsize]; /* fwstart.img is the only part which can't be testes by using *-elf - target. Check it against the checksum. This checksum is obtained with - sha512sum utility after compiling on Gnewsense. - */ - const grub_uint8_t fwstart_good_hash[] = - { 0x75, 0xbf, 0xa3, 0x0e, 0x7c, 0xd1, 0x03, 0x82, - 0xe1, 0x34, 0x55, 0xd7, 0x09, 0x1e, 0x6c, 0xcc, - 0xef, 0x08, 0x61, 0xc1, 0x3c, 0xd8, 0xc7, 0x9f, - 0xe8, 0x2d, 0x3d, 0xb2, 0xda, 0x41, 0xd3, 0x83, - 0xd7, 0xb8, 0xe3, 0xd7, 0x13, 0xec, 0x9b, 0xf6, - 0xf6, 0xae, 0x6b, 0x32, 0x29, 0xc1, 0x69, 0x82, - 0xfa, 0x65, 0x2d, 0x97, 0x3e, 0x83, 0x6e, 0x6c, - 0xce, 0x34, 0x10, 0x59, 0x74, 0x0e, 0x96, 0x26 }; - - boot_path = grub_util_get_path (dir, "fwstart.img"); + target. Check it against the checksum. */ + /* Wasn't retested after important changes. */ + const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + /* None yet. */ + const grub_uint8_t fuloong_fwstart_good_hash[512 / 8] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + const grub_uint8_t *fwstart_good_hash; + + if (image_target->id == IMAGE_FULOONG_FLASH) + { + fwstart_good_hash = fuloong_fwstart_good_hash; + boot_path = grub_util_get_path (dir, "fwstart_fuloong.img"); + } + else + { + fwstart_good_hash = yeeloong_fwstart_good_hash; + boot_path = grub_util_get_path (dir, "fwstart.img"); + } boot_size = grub_util_get_image_size (boot_path); boot_img = grub_util_read_image (boot_path); @@ -1403,12 +1461,12 @@ usage (int status) char *ptr; unsigned i; for (i = 0; i < ARRAY_SIZE (image_targets); i++) - format_len += strlen (image_targets[i].name) + 2; + format_len += strlen (image_targets[i].names[0]) + 2; ptr = formats = xmalloc (format_len); for (i = 0; i < ARRAY_SIZE (image_targets); i++) { - strcpy (ptr, image_targets[i].name); - ptr += strlen (image_targets[i].name); + strcpy (ptr, image_targets[i].names[0]); + ptr += strlen (image_targets[i].names[0]); *ptr++ = ','; *ptr++ = ' '; } @@ -1478,10 +1536,12 @@ main (int argc, char *argv[]) case 'O': { - unsigned i; + unsigned i, j; for (i = 0; i < ARRAY_SIZE (image_targets); i++) - if (strcmp (optarg, image_targets[i].name) == 0) - image_target = &image_targets[i]; + for (j = 0; image_targets[i].names[j] + && j < ARRAY_SIZE (image_targets[i].names); j++) + if (strcmp (optarg, image_targets[i].names[j]) == 0) + image_target = &image_targets[i]; if (!image_target) { printf ("unknown target format %s\n", optarg); @@ -1576,19 +1636,11 @@ main (int argc, char *argv[]) if (!dir) { - const char *last; - last = strchr (image_target->name, '-'); - if (last) - last = strchr (last + 1, '-'); - if (!last) - last = image_target->name + strlen (image_target->name); - dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name) - + 1); + dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR) + + grub_strlen (image_target->dirname) + 1); memcpy (dir, GRUB_PKGLIBROOTDIR, sizeof (GRUB_PKGLIBROOTDIR) - 1); *(dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/'; - memcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->name, - last - image_target->name); - *(dir + sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name)) = 0; + strcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->dirname); } generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp, From 307ed0b484330ed600cb01e33f45f6a974aae7c1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 25 Jan 2011 12:28:11 +0000 Subject: [PATCH 115/211] remove unused variables --- grub-core/kern/emu/getroot.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 0035c734a..4f8a0e8a7 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -573,9 +573,8 @@ grub_util_is_lvm (const char *os_dev) { struct dm_tree *tree; uint32_t maj, min; - struct dm_tree_node *node = NULL, *child; - void *handle; - const char *node_uuid, *mapper_name = NULL, *child_uuid, *child_name; + struct dm_tree_node *node = NULL; + const char *node_uuid; struct stat st; if (stat (os_dev, &st) < 0) From 118fb264ee5e92e43a57a82a7a262a08a850b8b3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 25 Jan 2011 16:51:23 +0000 Subject: [PATCH 116/211] Support probing multipath disks. --- grub-core/kern/emu/hostdisk.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index eb84d0220..ea42d945e 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1271,6 +1271,16 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) node = NULL; goto devmapper_out; } + if (strncmp (node_uuid, "mpath-", 6) == 0) + { + /* Multipath partitions have partN-mpath-* UUIDs, and are + linear mappings so are handled by + grub_util_get_dm_node_linear_info. Multipath disks are not + linear mappings and must be handled specially. */ + grub_dprintf ("hostdisk", "%s is a multipath disk\n", path); + mapper_name = dm_tree_node_get_name (node); + goto devmapper_out; + } if (strncmp (node_uuid, "DMRAID-", 7) != 0) { int major, minor; From 54da1febceee8e07edf6b58f31952648897ba689 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 19 Feb 2011 13:18:05 +0100 Subject: [PATCH 117/211] Rename mipsel-yeeloong to mipsel-loongson --- conf/Makefile.common | 2 +- configure.ac | 16 +++--- gentpl.py | 12 ++-- grub-core/Makefile.am | 2 +- grub-core/Makefile.core.def | 50 ++++++++--------- .../mips/{yeeloong => loongson}/fuloong.S | 0 .../mips/{yeeloong => loongson}/fwstart.S | 6 +- grub-core/boot/mips/startup_raw.S | 2 +- grub-core/bus/pci.c | 12 ++-- .../mips/{yeeloong => loongson}/lsspd.c | 0 grub-core/kern/main.c | 4 +- .../kern/mips/{yeeloong => loongson}/init.c | 6 +- grub-core/kern/mips/startup.S | 6 +- grub-core/loader/mips/linux.c | 8 +-- .../mips/{yeeloong => loongson}/uppermem.c | 0 grub-core/term/at_keyboard.c | 4 +- grub-core/term/ns8250.c | 8 +-- grub-core/term/serial.c | 4 +- .../mips/{yeeloong => loongson}/at_keyboard.h | 0 .../grub/mips/{yeeloong => loongson}/cmos.h | 0 include/grub/mips/{yeeloong => loongson}/ec.h | 0 .../grub/mips/{yeeloong => loongson}/kernel.h | 0 .../grub/mips/{yeeloong => loongson}/memory.h | 0 .../grub/mips/{yeeloong => loongson}/pci.h | 8 +-- .../grub/mips/{yeeloong => loongson}/serial.h | 0 .../grub/mips/{yeeloong => loongson}/time.h | 0 include/grub/offsets.h | 16 +++--- include/grub/serial.h | 2 +- util/grub-install.in | 6 +- util/grub-mkimage.c | 56 +++++++++---------- 30 files changed, 116 insertions(+), 114 deletions(-) rename grub-core/boot/mips/{yeeloong => loongson}/fuloong.S (100%) rename grub-core/boot/mips/{yeeloong => loongson}/fwstart.S (99%) rename grub-core/commands/mips/{yeeloong => loongson}/lsspd.c (100%) rename grub-core/kern/mips/{yeeloong => loongson}/init.c (98%) rename grub-core/mmap/mips/{yeeloong => loongson}/uppermem.c (100%) rename include/grub/mips/{yeeloong => loongson}/at_keyboard.h (100%) rename include/grub/mips/{yeeloong => loongson}/cmos.h (100%) rename include/grub/mips/{yeeloong => loongson}/ec.h (100%) rename include/grub/mips/{yeeloong => loongson}/kernel.h (100%) rename include/grub/mips/{yeeloong => loongson}/memory.h (100%) rename include/grub/mips/{yeeloong => loongson}/pci.h (95%) rename include/grub/mips/{yeeloong => loongson}/serial.h (100%) rename include/grub/mips/{yeeloong => loongson}/time.h (100%) diff --git a/conf/Makefile.common b/conf/Makefile.common index 32ca76d08..2c08d4df9 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -21,7 +21,7 @@ endif if COND_i386_ieee1275 CFLAGS_PLATFORM += -mrtd -mregparm=3 endif -if COND_mips_yeeloong +if COND_mips_loongson CFLAGS_PLATFORM += -mexplicit-relocs CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK CCASFLAGS_PLATFORM = -march=mips3 diff --git a/configure.ac b/configure.ac index c660ac41e..64d6daf2b 100644 --- a/configure.ac +++ b/configure.ac @@ -96,7 +96,7 @@ if test "x$with_platform" = x; then powerpc-*) platform=ieee1275 ;; powerpc64-*) platform=ieee1275 ;; sparc64-*) platform=ieee1275 ;; - mips-*) platform=yeeloong ;; + mips-*) platform=loongson ;; *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;; esac else @@ -123,7 +123,9 @@ case "$target_cpu"-"$platform" in powerpc-ieee1275) ;; sparc64-ieee1275) ;; mips-qemu-mips) ;; - mips-yeeloong) ;; + mips-yeeloong) platform=loongson ;; + mips-fuloong) platform=loongson ;; + mips-loongson) ;; *-emu) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; esac @@ -156,7 +158,7 @@ case "$platform" in qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;; pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;; emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; - yeeloong) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; + loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; qemu-mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; esac case "$target_cpu" in @@ -219,8 +221,8 @@ for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do done done -if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xyeeloong ); then - AC_MSG_ERROR([qemu and yeeloong ports need unifont]) +if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson ); then + AC_MSG_ERROR([qemu and loongson ports need unifont]) fi AC_SUBST([FONT_SOURCE]) @@ -398,7 +400,7 @@ if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm" fi -if test "${target_cpu}-${platform}" = mips-yeeloong; then +if test "${target_cpu}-${platform}" = mips-loongson; then AC_CACHE_CHECK([whether -march=loongson2f works], [grub_cv_cc_march_loongson2f], [ SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -march=loongson2f" @@ -941,7 +943,7 @@ AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot]) AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot]) AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) -AM_CONDITIONAL([COND_mips_yeeloong], [test x$target_cpu = xmips -a x$platform = xyeeloong]) +AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmips -a x$platform = xloongson]) AM_CONDITIONAL([COND_mips_qemu_mips], [test x$target_cpu = xmips -a x$platform = xqemu_mips]) AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) diff --git a/gentpl.py b/gentpl.py index a42a60667..17c6abfd8 100644 --- a/gentpl.py +++ b/gentpl.py @@ -6,7 +6,7 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275", "x86_64_efi", - "mips_yeeloong", "sparc64_ieee1275", + "mips_loongson", "sparc64_ieee1275", "powerpc_ieee1275" ] GROUPS = {} @@ -17,7 +17,7 @@ GROUPS["common"] = GRUB_PLATFORMS[:] GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ] GROUPS["x86_64"] = [ "x86_64_efi" ] GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] -GROUPS["mips"] = [ "mips_yeeloong" ] +GROUPS["mips"] = [ "mips_loongson" ] GROUPS["sparc64"] = [ "sparc64_ieee1275" ] GROUPS["powerpc"] = [ "powerpc_ieee1275" ] @@ -29,17 +29,17 @@ GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") # Groups based on hardware features -GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_yeeloong"]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi") +GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson"]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi") GROUPS["pci"] = GROUPS["x86"] + GROUPS["mips"] GROUPS["usb"] = GROUPS["pci"] # If gfxterm is main output console integrate it into kernel -GROUPS["videoinkernel"] = ["mips_yeeloong"] +GROUPS["videoinkernel"] = ["mips_loongson"] GROUPS["videomodules"] = GRUB_PLATFORMS[:]; for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) # Similar for terminfo -GROUPS["terminfoinkernel"] = ["mips_yeeloong"] + GROUPS["ieee1275"]; +GROUPS["terminfoinkernel"] = ["mips_loongson"] + GROUPS["ieee1275"]; GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) @@ -238,7 +238,7 @@ def foreach_enabled_platform(closure): # noemu = bus/usb/usbhub.c; # enable = emu; # enable = i386; -# enable = mips_yeeloong; +# enable = mips_loongson; # emu_condition = COND_GRUB_EMU_USB; # }; # diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 94f7f3ffe..3b1611db2 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -125,7 +125,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif -if COND_mips_yeeloong +if COND_mips_loongson KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index e651e1596..a87eb1598 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -32,11 +32,11 @@ kernel = { i386_coreboot_ldflags = '-Wl,-Ttext=0x8200'; i386_multiboot_ldflags = '-Wl,-Ttext=0x8200'; i386_ieee1275_ldflags = '-Wl,-Ttext=0x10000'; - mips_yeeloong_ldflags = '-Wl,-Ttext,0x80200000'; + mips_loongson_ldflags = '-Wl,-Ttext,0x80200000'; powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; - mips_yeeloong_cppflags = '-DUSE_ASCII_FAILBACK'; + mips_loongson_cppflags = '-DUSE_ASCII_FAILBACK'; i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; emu_cflags = '$(CFLAGS_GNULIB)'; emu_cppflags = '$(CPPFLAGS_GNULIB)'; @@ -48,7 +48,7 @@ kernel = { i386_ieee1275_startup = kern/i386/ieee1275/startup.S; i386_coreboot_startup = kern/i386/coreboot/startup.S; i386_multiboot_startup = kern/i386/coreboot/startup.S; - mips_yeeloong_startup = kern/mips/startup.S; + mips_loongson_startup = kern/mips/startup.S; sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; @@ -81,7 +81,7 @@ kernel = { i386_qemu = kern/generic/rtc_get_time_ms.c; i386_coreboot = kern/generic/rtc_get_time_ms.c; i386_multiboot = kern/generic/rtc_get_time_ms.c; - mips_yeeloong = kern/generic/rtc_get_time_ms.c; + mips_loongson = kern/generic/rtc_get_time_ms.c; ieee1275 = disk/ieee1275/ofdisk.c; ieee1275 = kern/ieee1275/cmain.c; @@ -136,20 +136,20 @@ kernel = { i386_ieee1275 = kern/ieee1275/init.c; - mips_yeeloong = term/ns8250.c; - mips_yeeloong = bus/bonito.c; - mips_yeeloong = bus/cs5536.c; - mips_yeeloong = bus/pci.c; - mips_yeeloong = kern/mips/cache.S; - mips_yeeloong = kern/mips/dl.c; - mips_yeeloong = kern/mips/init.c; - mips_yeeloong = kern/mips/yeeloong/init.c; - mips_yeeloong = term/at_keyboard.c; - mips_yeeloong = term/serial.c; - mips_yeeloong = video/sm712.c; - mips_yeeloong = video/sis315pro.c; + mips_loongson = term/ns8250.c; + mips_loongson = bus/bonito.c; + mips_loongson = bus/cs5536.c; + mips_loongson = bus/pci.c; + mips_loongson = kern/mips/cache.S; + mips_loongson = kern/mips/dl.c; + mips_loongson = kern/mips/init.c; + mips_loongson = kern/mips/loongson/init.c; + mips_loongson = term/at_keyboard.c; + mips_loongson = term/serial.c; + mips_loongson = video/sm712.c; + mips_loongson = video/sis315pro.c; extra_dist = video/sm712_init.c; - mips_yeeloong = commands/keylayouts.c; + mips_loongson = commands/keylayouts.c; powerpc_ieee1275 = kern/ieee1275/init.c; powerpc_ieee1275 = kern/powerpc/cache.S; @@ -323,18 +323,18 @@ image = { image = { name = fwstart; - mips_yeeloong = boot/mips/yeeloong/fwstart.S; + mips_loongson = boot/mips/loongson/fwstart.S; objcopyflags = '-O binary'; ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; - enable = mips_yeeloong; + enable = mips_loongson; }; image = { name = fwstart_fuloong; - mips_yeeloong = boot/mips/yeeloong/fuloong.S; + mips_loongson = boot/mips/loongson/fuloong.S; objcopyflags = '-O binary'; ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; - enable = mips_yeeloong; + enable = mips_loongson; }; module = { @@ -358,8 +358,8 @@ module = { module = { name = lsspd; - mips_yeeloong = commands/mips/yeeloong/lsspd.c; - enable = mips_yeeloong; + mips_loongson = commands/mips/loongson/lsspd.c; + enable = mips_loongson; }; module = { @@ -1236,10 +1236,10 @@ module = { x86_efi = mmap/efi/mmap.c; - mips_yeeloong = mmap/mips/yeeloong/uppermem.c; + mips_loongson = mmap/mips/loongson/uppermem.c; enable = x86; - enable = mips_yeeloong; + enable = mips_loongson; }; module = { diff --git a/grub-core/boot/mips/yeeloong/fuloong.S b/grub-core/boot/mips/loongson/fuloong.S similarity index 100% rename from grub-core/boot/mips/yeeloong/fuloong.S rename to grub-core/boot/mips/loongson/fuloong.S diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/loongson/fwstart.S similarity index 99% rename from grub-core/boot/mips/yeeloong/fwstart.S rename to grub-core/boot/mips/loongson/fwstart.S index d25ff1a5b..6deb17f2b 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/loongson/fwstart.S @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include -#include +#include +#include #include #include #include @@ -129,7 +129,7 @@ retry_cs5536: sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0) sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0) - /* Yeeloong has only one memory slot. */ + /* Yeeloong and Fuloong have only one memory slot. */ /* Output first byte on serial for debugging. */ ori $a1, $zero, GRUB_SMB_RAM_START_ADDR bal read_spd diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index d8789982f..0bb3ea11f 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -50,7 +50,7 @@ codestart: /* Parse arguments. Has to be done before relocation. So need to do it in asm. */ -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON move $s2, $zero move $s3, $zero move $s4, $zero diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c index 11101d42b..bf9e605ae 100644 --- a/grub-core/bus/pci.c +++ b/grub-core/bus/pci.c @@ -36,7 +36,7 @@ grub_dma_free (struct grub_pci_dma_chunk *ch) } /* #endif */ -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON volatile void * grub_dma_get_virt (struct grub_pci_dma_chunk *ch) { @@ -99,13 +99,13 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) continue; } -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON /* Skip ghosts. */ - if (id == GRUB_YEELOONG_OHCI_PCIID - && dev.function == GRUB_YEELOONG_OHCI_GHOST_FUNCTION) + if (id == GRUB_LOONGSON_OHCI_PCIID + && dev.function == GRUB_LOONGSON_OHCI_GHOST_FUNCTION) continue; - if (id == GRUB_YEELOONG_EHCI_PCIID - && dev.function == GRUB_YEELOONG_EHCI_GHOST_FUNCTION) + if (id == GRUB_LOONGSON_EHCI_PCIID + && dev.function == GRUB_LOONGSON_EHCI_GHOST_FUNCTION) continue; #endif diff --git a/grub-core/commands/mips/yeeloong/lsspd.c b/grub-core/commands/mips/loongson/lsspd.c similarity index 100% rename from grub-core/commands/mips/yeeloong/lsspd.c rename to grub-core/commands/mips/loongson/lsspd.c diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index da7123234..6376c2516 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -53,8 +53,8 @@ grub_module_iterate (int (*hook) (struct grub_module_header *header)) } } -/* This is actualy platform-independant but used only on yeeloong and sparc. */ -#if defined (GRUB_MACHINE_MIPS_YEELOONG) || defined (GRUB_MACHINE_SPARC64) +/* This is actualy platform-independant but used only on loongson and sparc. */ +#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_SPARC64) grub_addr_t grub_modules_get_end (void) { diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/loongson/init.c similarity index 98% rename from grub-core/kern/mips/yeeloong/init.c rename to grub-core/kern/mips/loongson/init.c index 7526111cc..acc3a17c7 100644 --- a/grub-core/kern/mips/yeeloong/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -80,7 +80,7 @@ init_pci (void) /* FIXME: autoscan for BARs and devices. */ switch (pciid) { - case GRUB_YEELOONG_OHCI_PCIID: + case GRUB_LOONGSON_OHCI_PCIID: addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); grub_pci_write (addr, 0x5025000); addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); @@ -92,7 +92,7 @@ init_pci (void) addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES); break; - case GRUB_YEELOONG_EHCI_PCIID: + case GRUB_LOONGSON_EHCI_PCIID: addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); grub_pci_write (addr, 0x5026000); addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); @@ -164,7 +164,7 @@ grub_machine_init (void) if (err) grub_fatal ("Couldn't init SMBus: %s\n", grub_errmsg); - /* Yeeloong has only one memory slot. */ + /* Yeeloong and Fuloong have only one memory slot. */ err = grub_cs5536_read_spd (smbbase, GRUB_SMB_RAM_START_ADDR, &spd); if (err) grub_fatal ("Couldn't read SPD: %s\n", grub_errmsg); diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 999beee79..624ceb6d0 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -36,7 +36,7 @@ start: bal cont nop - . = _start + GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE + . = _start + GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE total_module_size: .long 0 @@ -51,7 +51,7 @@ VARIABLE(grub_prefix) */ . = _start + GRUB_KERNEL_MACHINE_PREFIX_END -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON VARIABLE (grub_arch_busclock) .long 0 VARIABLE (grub_arch_cpuclock) @@ -67,7 +67,7 @@ cont: /* Save our base. */ move $s0, $ra -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON lui $t1, %hi(grub_arch_busclock) addiu $t1, %lo(grub_arch_busclock) sw $s2, 0($t1) diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 244d2b8a3..9cc1bd778 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -32,7 +32,7 @@ #include #include -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON #include const char loongson_machtypes[][60] = @@ -224,7 +224,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* For arguments. */ linux_argc = argc; -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON linux_argc++; #endif /* Main arguments. */ @@ -239,7 +239,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* Normal arguments. */ for (i = 1; i < argc; i++) size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON size += ALIGN_UP (sizeof (loongson_machtypes[0]), 4); #endif @@ -279,7 +279,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_argv++; linux_args += ALIGN_UP (sizeof ("a0"), 4); -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON { unsigned mtype = grub_arch_machine; if (mtype >= ARRAY_SIZE (loongson_machtypes)) diff --git a/grub-core/mmap/mips/yeeloong/uppermem.c b/grub-core/mmap/mips/loongson/uppermem.c similarity index 100% rename from grub-core/mmap/mips/yeeloong/uppermem.c rename to grub-core/mmap/mips/loongson/uppermem.c diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index 55cb76483..828217497 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -257,7 +257,7 @@ grub_keyboard_controller_write (grub_uint8_t c) grub_outb (c, KEYBOARD_REG_DATA); } -#if !defined (GRUB_MACHINE_MIPS_YEELOONG) && !defined (GRUB_MACHINE_QEMU) +#if !defined (GRUB_MACHINE_MIPS_LOONGSON) && !defined (GRUB_MACHINE_QEMU) static grub_uint8_t grub_keyboard_controller_read (void) @@ -562,7 +562,7 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus keyboard_controller_wait_until_ready (); grub_inb (KEYBOARD_REG_DATA); } -#if defined (GRUB_MACHINE_MIPS_YEELOONG) || defined (GRUB_MACHINE_QEMU) +#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_QEMU) grub_keyboard_controller_orig = 0; grub_keyboard_orig_set = 2; #else diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c index 5d403c845..b63ee14d9 100644 --- a/grub-core/term/ns8250.c +++ b/grub-core/term/ns8250.c @@ -66,8 +66,8 @@ serial_get_divisor (const struct grub_serial_port *port, for (i = 0; i < ARRAY_SIZE (divisor_tab); i++) if (divisor_tab[i].speed == config->speed) { - /* internal UART in Yeeloong runs twice the usual rate. */ -#ifdef GRUB_MACHINE_MIPS_YEELOONG + /* internal Loongson UART runs twice the usual rate. */ +#ifdef GRUB_MACHINE_MIPS_LOONGSON if (port->port == 0xbff003f8) return 2 * divisor_tab[i].div; else @@ -115,8 +115,8 @@ do_real_config (struct grub_serial_port *port) | stop_bits[port->config.stop_bits]); grub_outb (status, port->port + UART_LCR); - /* In Yeeloong serial port has only 3 wires. */ -#ifndef GRUB_MACHINE_MIPS_YEELOONG + /* On Loongson machines serial port has only 3 wires. */ +#ifndef GRUB_MACHINE_MIPS_LOONGSON /* Enable the FIFO. */ grub_outb (UART_ENABLE_FIFO_TRIGGER1, port->port + UART_FCR); diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index aca5769fd..74c493da1 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -26,7 +26,7 @@ #include #include #include -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON #include #endif @@ -298,7 +298,7 @@ grub_serial_register (struct grub_serial_port *port) port->term_in = in; port->term_out = out; grub_terminfo_output_register (out, "vt100"); -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON if (grub_strcmp (port->name, (grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG) ? "com0" : "com2") == 0) diff --git a/include/grub/mips/yeeloong/at_keyboard.h b/include/grub/mips/loongson/at_keyboard.h similarity index 100% rename from include/grub/mips/yeeloong/at_keyboard.h rename to include/grub/mips/loongson/at_keyboard.h diff --git a/include/grub/mips/yeeloong/cmos.h b/include/grub/mips/loongson/cmos.h similarity index 100% rename from include/grub/mips/yeeloong/cmos.h rename to include/grub/mips/loongson/cmos.h diff --git a/include/grub/mips/yeeloong/ec.h b/include/grub/mips/loongson/ec.h similarity index 100% rename from include/grub/mips/yeeloong/ec.h rename to include/grub/mips/loongson/ec.h diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/loongson/kernel.h similarity index 100% rename from include/grub/mips/yeeloong/kernel.h rename to include/grub/mips/loongson/kernel.h diff --git a/include/grub/mips/yeeloong/memory.h b/include/grub/mips/loongson/memory.h similarity index 100% rename from include/grub/mips/yeeloong/memory.h rename to include/grub/mips/loongson/memory.h diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/loongson/pci.h similarity index 95% rename from include/grub/mips/yeeloong/pci.h rename to include/grub/mips/loongson/pci.h index 199bac048..3f828c2f8 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/loongson/pci.h @@ -24,10 +24,10 @@ #include #endif -#define GRUB_YEELOONG_OHCI_PCIID 0x00351033 -#define GRUB_YEELOONG_EHCI_PCIID 0x00e01033 -#define GRUB_YEELOONG_OHCI_GHOST_FUNCTION 4 -#define GRUB_YEELOONG_EHCI_GHOST_FUNCTION 5 +#define GRUB_LOONGSON_OHCI_PCIID 0x00351033 +#define GRUB_LOONGSON_EHCI_PCIID 0x00e01033 +#define GRUB_LOONGSON_OHCI_GHOST_FUNCTION 4 +#define GRUB_LOONGSON_EHCI_GHOST_FUNCTION 5 #define GRUB_PCI_NUM_BUS 1 #define GRUB_PCI_NUM_DEVICES 16 diff --git a/include/grub/mips/yeeloong/serial.h b/include/grub/mips/loongson/serial.h similarity index 100% rename from include/grub/mips/yeeloong/serial.h rename to include/grub/mips/loongson/serial.h diff --git a/include/grub/mips/yeeloong/time.h b/include/grub/mips/loongson/time.h similarity index 100% rename from include/grub/mips/yeeloong/time.h rename to include/grub/mips/loongson/time.h diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 817372b69..7d88f344d 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -100,16 +100,16 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 -#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR 0x80200000 +#define GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR 0x80200000 -#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN 32 +#define GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN 32 -#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE 0xc +#define GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE 0xc -#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE 0x08 -#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX 0x0c -#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END 0x54 +#define GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE 0x08 +#define GRUB_KERNEL_MIPS_LOONGSON_PREFIX 0x0c +#define GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END 0x54 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_EFI_PREFIX 0x8 @@ -144,7 +144,7 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 -#define GRUB_KERNEL_MIPS_YEELOONG_MOD_ALIGN 0x1 +#define GRUB_KERNEL_MIPS_LOONGSON_MOD_ALIGN 0x1 /* Minimal gap between _end and the start of the modules. It's a hack for PowerMac to prevent "CLAIM failed" error. The real fix is to diff --git a/include/grub/serial.h b/include/grub/serial.h index 9540bee64..41b720891 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -102,7 +102,7 @@ grub_serial_config_defaults (struct grub_serial_port *port) { struct grub_serial_config config = { -#ifdef GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_LOONGSON .speed = 115200, #else .speed = 9600, diff --git a/util/grub-install.in b/util/grub-install.in index 90360c279..b20cadaf6 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -551,13 +551,13 @@ fi case "${target_cpu}-${platform}" in sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; - mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; + mips-loongson) mkimage_target=mipsel-loongson-elf ;; *) mkimage_target="${target_cpu}-${platform}" ;; esac case "${target_cpu}-${platform}" in i386-efi | x86_64-efi) imgext=efi ;; - mips-yeeloong | i386-coreboot | i386-multiboot | i386-ieee1275 \ + mips-loongson | i386-coreboot | i386-multiboot | i386-ieee1275 \ | powerpc-ieee1275) imgext=elf ;; *) imgext=img ;; esac @@ -566,7 +566,7 @@ esac "$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $modules || exit 1 # Backward-compatibility kludges -if [ "${target_cpu}-${platform}" = "mips-yeeloong" ]; then +if [ "${target_cpu}-${platform}" = "mips-loongson" ]; then cp "${grubdir}/core.${imgext}" "${bootdir}"/grub.elf elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then cp "${grubdir}/core.${imgext}" "${grubdir}/grub" diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 663e60f08..739b8c16e 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -65,7 +65,7 @@ struct image_target_desc enum { IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, - IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, + IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, IMAGE_FULOONG_FLASH, IMAGE_I386_PC_PXE } id; enum @@ -265,70 +265,70 @@ struct image_target_desc image_targets[] = .install_bsd_part = TARGET_NO_FIELD, }, { - .dirname = "mipsel-yeeloong", + .dirname = "mipsel-loongson", .names = { "mipsel-yeeloong-flash", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_YEELOONG_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, + .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, + .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, .raw_size = 0, - .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, + .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, + .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, .elf_target = EM_MIPS, - .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN, + .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, .default_compression = COMPRESSION_NONE }, { - .dirname = "mipsel-yeeloong", + .dirname = "mipsel-loongson", .names = { "mipsel-fuloong-flash", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_FULOONG_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, + .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, + .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, .raw_size = 0, - .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, + .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, + .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, .elf_target = EM_MIPS, - .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN, + .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, .default_compression = COMPRESSION_NONE }, { - .dirname = "mipsel-yeeloong", + .dirname = "mipsel-loongson", .names = { "mipsel-loongson-elf", "mipsel-yeeloong-elf", "mipsel-fuloong-elf", NULL }, .voidp_sizeof = 4, .bigendian = 0, - .id = IMAGE_YEELOONG_ELF, + .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, + .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, + .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, .raw_size = 0, - .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, + .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, + .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, .elf_target = EM_MIPS, - .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN, + .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, .default_compression = COMPRESSION_NONE }, { @@ -837,10 +837,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], decompress_size = grub_util_get_image_size (decompress_path); decompress_img = grub_util_read_image (decompress_path); - *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE)) + *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE)) = grub_host_to_target32 (core_size); - *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE)) + *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE)) = grub_host_to_target32 (kernel_size + total_module_size); full_size = core_size + decompress_size; @@ -1271,7 +1271,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], core_size = rom_size; } break; - case IMAGE_YEELOONG_ELF: + case IMAGE_LOONGSON_ELF: case IMAGE_PPC: case IMAGE_COREBOOT: case IMAGE_I386_IEEE1275: @@ -1284,7 +1284,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], int header_size, footer_size = 0; int phnum = 1; - if (image_target->id != IMAGE_YEELOONG_ELF) + if (image_target->id != IMAGE_LOONGSON_ELF) phnum += 2; if (note) @@ -1319,7 +1319,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], /* No section headers. */ ehdr->e_shoff = grub_host_to_target32 (0); - if (image_target->id == IMAGE_YEELOONG_ELF) + if (image_target->id == IMAGE_LOONGSON_ELF) ehdr->e_shentsize = grub_host_to_target16 (0); else ehdr->e_shentsize = grub_host_to_target16 (sizeof (Elf32_Shdr)); @@ -1332,7 +1332,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr->p_offset = grub_host_to_target32 (header_size); phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - if (image_target->id == IMAGE_YEELOONG_ELF) + if (image_target->id == IMAGE_LOONGSON_ELF) target_addr = ALIGN_UP (image_target->link_addr + kernel_size + total_module_size, 32); else @@ -1341,12 +1341,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); phdr->p_align = grub_host_to_target32 (align > image_target->link_align ? align : image_target->link_align); - if (image_target->id == IMAGE_YEELOONG_ELF) + if (image_target->id == IMAGE_LOONGSON_ELF) ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER | EF_MIPS_PIC | EF_MIPS_CPIC); else ehdr->e_flags = 0; - if (image_target->id == IMAGE_YEELOONG_ELF) + if (image_target->id == IMAGE_LOONGSON_ELF) { phdr->p_filesz = grub_host_to_target32 (core_size); phdr->p_memsz = grub_host_to_target32 (core_size); From cf4d3fa6407417a6ecdc82ed886484400789cde5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 18:34:05 +0200 Subject: [PATCH 118/211] Send blend_text_bg when any backgorund is set as opposed to only when streteched background is set --- grub-core/term/gfxterm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 8a75df93c..1d850abd4 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -1174,7 +1174,6 @@ grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, /* Replace the original bitmap with the scaled one. */ grub_video_bitmap_destroy (bitmap); bitmap = scaled_bitmap; - blend_text_bg = 1; } } } @@ -1182,6 +1181,8 @@ grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, /* If bitmap was loaded correctly, display it. */ if (bitmap) { + blend_text_bg = 1; + /* Determine bitmap dimensions. */ bitmap_width = grub_video_bitmap_get_width (bitmap); bitmap_height = grub_video_bitmap_get_height (bitmap); From b38a4983949bbf66a7ecdae3423b2401ce2e635f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Apr 2011 14:40:15 +0200 Subject: [PATCH 119/211] BPB patching support (untested) --- grub-core/fs/fat.c | 47 +------------ grub-core/loader/i386/pc/chainloader.c | 91 ++++++++++++++++++++++++-- grub-core/loader/i386/pc/ntldr.c | 2 + grub-core/normal/main.c | 3 + include/grub/i386/pc/chainloader.h | 7 +- include/grub/ntfs.h | 8 ++- 6 files changed, 99 insertions(+), 59 deletions(-) diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 89050943c..7906cf1b2 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -26,6 +26,7 @@ #include #include #include +#include #define GRUB_FAT_DIR_ENTRY_SIZE 32 @@ -49,52 +50,6 @@ | GRUB_FAT_ATTR_ARCHIVE \ | GRUB_FAT_ATTR_VOLUME_ID) -struct grub_fat_bpb -{ - grub_uint8_t jmp_boot[3]; - grub_uint8_t oem_name[8]; - grub_uint16_t bytes_per_sector; - grub_uint8_t sectors_per_cluster; - grub_uint16_t num_reserved_sectors; - grub_uint8_t num_fats; - grub_uint16_t num_root_entries; - grub_uint16_t num_total_sectors_16; - grub_uint8_t media; - grub_uint16_t sectors_per_fat_16; - grub_uint16_t sectors_per_track; - grub_uint16_t num_heads; - grub_uint32_t num_hidden_sectors; - grub_uint32_t num_total_sectors_32; - union - { - struct - { - grub_uint8_t num_ph_drive; - grub_uint8_t reserved; - grub_uint8_t boot_sig; - grub_uint32_t num_serial; - grub_uint8_t label[11]; - grub_uint8_t fstype[8]; - } __attribute__ ((packed)) fat12_or_fat16; - struct - { - grub_uint32_t sectors_per_fat_32; - grub_uint16_t extended_flags; - grub_uint16_t fs_version; - grub_uint32_t root_cluster; - grub_uint16_t fs_info; - grub_uint16_t backup_boot_sector; - grub_uint8_t reserved[12]; - grub_uint8_t num_ph_drive; - grub_uint8_t reserved1; - grub_uint8_t boot_sig; - grub_uint32_t num_serial; - grub_uint8_t label[11]; - grub_uint8_t fstype[8]; - } __attribute__ ((packed)) fat32; - } __attribute__ ((packed)) version_specific; -} __attribute__ ((packed)); - struct grub_fat_dir_entry { grub_uint8_t name[11]; diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c index fd99c81d5..174e5b7a5 100644 --- a/grub-core/loader/i386/pc/chainloader.c +++ b/grub-core/loader/i386/pc/chainloader.c @@ -37,11 +37,19 @@ #include #include #include +#include +#include static grub_dl_t my_mod; static int boot_drive; static void *boot_part_addr; +typedef enum + { + GRUB_CHAINLOADER_FORCE = 0x1, + GRUB_CHAINLOADER_BPB = 0x2, + } grub_chainloader_flags_t; + static grub_err_t grub_chainloader_boot (void) { @@ -59,6 +67,63 @@ grub_chainloader_unload (void) return GRUB_ERR_NONE; } +void +grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl) +{ + grub_uint32_t part_start = 0; + if (dev && dev->disk) + part_start = grub_partition_get_start (dev->disk->partition); + if (grub_memcmp ((char *) &((struct grub_ntfs_bpb *) bs)->oem_name, + "NTFS", 4) == 0) + { + struct grub_ntfs_bpb *bpb = (struct grub_ntfs_bpb *) bs; + bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start); + bpb->bios_drive = dl; + return; + } + + do + { + struct grub_fat_bpb *bpb = (struct grub_fat_bpb *) bs; + if (grub_strncmp((const char *) bpb->version_specific.fat12_or_fat16.fstype, "FAT12", 5) + && grub_strncmp((const char *) bpb->version_specific.fat12_or_fat16.fstype, "FAT16", 5) + && grub_strncmp((const char *) bpb->version_specific.fat32.fstype, "FAT32", 5)) + break; + + if (grub_le_to_cpu16 (bpb->bytes_per_sector) < 512 + || (grub_le_to_cpu16 (bpb->bytes_per_sector) + & (grub_le_to_cpu16 (bpb->bytes_per_sector) - 1))) + break; + + if (bpb->sectors_per_cluster == 0 + || (bpb->sectors_per_cluster & (bpb->sectors_per_cluster - 1))) + break; + + if (bpb->num_reserved_sectors == 0) + break; + if (bpb->num_total_sectors_16 == 0 || bpb->num_total_sectors_32 == 0) + break; + + if (bpb->num_fats == 0) + break; + + if (bpb->sectors_per_fat_16) + { + bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start); + bpb->version_specific.fat12_or_fat16.num_ph_drive = dl; + return; + } + if (bpb->version_specific.fat32.sectors_per_fat_32) + { + bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start); + bpb->version_specific.fat32.num_ph_drive = dl; + return; + } + break; + } + while (0); +} + static void grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) { @@ -119,6 +184,9 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) } } + if (flags & GRUB_CHAINLOADER_BPB) + grub_chainloader_patch_bpb ((void *) 0x7C00, dev, drive); + if (dev) grub_device_close (dev); @@ -145,11 +213,23 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), { grub_chainloader_flags_t flags = 0; - if (argc > 0 && grub_strcmp (argv[0], "--force") == 0) + while (argc > 0) { - flags |= GRUB_CHAINLOADER_FORCE; - argc--; - argv++; + if (grub_strcmp (argv[0], "--force") == 0) + { + flags |= GRUB_CHAINLOADER_FORCE; + argc--; + argv++; + continue; + } + if (grub_strcmp (argv[0], "--bpb") == 0) + { + flags |= GRUB_CHAINLOADER_BPB; + argc--; + argv++; + continue; + } + break; } if (argc == 0) @@ -165,7 +245,8 @@ static grub_command_t cmd; GRUB_MOD_INIT(chainloader) { cmd = grub_register_command ("chainloader", grub_cmd_chainloader, - 0, N_("Load another boot loader.")); + "[--force|--bpb] FILE", + N_("Load another boot loader.")); my_mod = mod; } diff --git a/grub-core/loader/i386/pc/ntldr.c b/grub-core/loader/i386/pc/ntldr.c index 0c33a0680..9649cdfbe 100644 --- a/grub-core/loader/i386/pc/ntldr.c +++ b/grub-core/loader/i386/pc/ntldr.c @@ -32,6 +32,7 @@ #include #include #include +#include static grub_dl_t my_mod; static struct grub_relocator *rel; @@ -110,6 +111,7 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)), grub_device_close (dev); goto fail; } + grub_chainloader_patch_bpb (bs, dev, edx); } if (dev) diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index cefb1cb9b..c04accb6d 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -515,6 +515,9 @@ GRUB_MOD_INIT(normal) /* Set default color names. */ grub_env_set ("color_normal", "white/black"); grub_env_set ("color_highlight", "black/white"); + + grub_env_set ("grub_feature_chainloader_bpb", "--bpb"); + grub_env_export ("grub_feature_chainloader_bpb"); } GRUB_MOD_FINI(normal) diff --git a/include/grub/i386/pc/chainloader.h b/include/grub/i386/pc/chainloader.h index ca1da23a7..4776b181b 100644 --- a/include/grub/i386/pc/chainloader.h +++ b/include/grub/i386/pc/chainloader.h @@ -21,10 +21,7 @@ #include -/* Common function for normal and rescue mode commands. */ -typedef enum - { - GRUB_CHAINLOADER_FORCE = 0x1 - } grub_chainloader_flags_t; +void +grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl); #endif /* GRUB_CHAINLOADER_MACHINE_HEADER */ diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h index 31b99398b..9e2e34707 100644 --- a/include/grub/ntfs.h +++ b/include/grub/ntfs.h @@ -106,14 +106,16 @@ struct grub_ntfs_bpb grub_uint16_t sectors_per_track; grub_uint16_t num_heads; grub_uint32_t num_hidden_sectors; - grub_uint32_t reserved_3[2]; + grub_uint32_t reserved_3; + grub_uint8_t bios_drive; + grub_uint8_t reserved_4[3]; grub_uint64_t num_total_sectors; grub_uint64_t mft_lcn; grub_uint64_t mft_mirr_lcn; grub_int8_t clusters_per_mft; - grub_int8_t reserved_4[3]; - grub_int8_t clusters_per_index; grub_int8_t reserved_5[3]; + grub_int8_t clusters_per_index; + grub_int8_t reserved_6[3]; grub_uint64_t num_serial; grub_uint32_t checksum; } __attribute__ ((packed)); From 5bfb6e71e8c3d189cc55542239a01794096344bb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Apr 2011 15:05:53 +0200 Subject: [PATCH 120/211] features support --- grub-core/normal/main.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index c04accb6d..fa20d0d78 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -471,9 +471,14 @@ grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)), static grub_command_t cmd_clear; static void (*grub_xputs_saved) (const char *str); +static const char *features[] = { + "feature_chainloader_bpb", "feature_ntldr" +}; GRUB_MOD_INIT(normal) { + unsigned i; + /* Previously many modules depended on gzio. Be nice to user and load it. */ grub_dl_load ("gzio"); @@ -516,8 +521,11 @@ GRUB_MOD_INIT(normal) grub_env_set ("color_normal", "white/black"); grub_env_set ("color_highlight", "black/white"); - grub_env_set ("grub_feature_chainloader_bpb", "--bpb"); - grub_env_export ("grub_feature_chainloader_bpb"); + for (i = 0; i < ARRAY_SIZE (features); i++) + { + grub_env_set (features[i], "y"); + grub_env_export (features[i]); + } } GRUB_MOD_FINI(normal) From 3dd3dd335fe8efb23d54bfbc322701d54c28a65d Mon Sep 17 00:00:00 2001 From: Feiran Zheng Date: Mon, 11 Apr 2011 08:16:13 +0200 Subject: [PATCH 121/211] minix3fs support --- grub-core/Makefile.core.def | 5 ++ grub-core/fs/minix.c | 164 +++++++++++++++++++++++++++--------- grub-core/fs/minix3.c | 2 + 3 files changed, 132 insertions(+), 39 deletions(-) create mode 100644 grub-core/fs/minix3.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7c26b37e9..9f418a0b7 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -958,6 +958,11 @@ module = { common = fs/minix2.c; }; +module = { + name = minix3; + common = fs/minix3.c; +}; + module = { name = nilfs2; common = fs/nilfs2.c; diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 679e1ec51..c93dfe085 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -25,14 +25,17 @@ #include #include -#ifdef MODE_MINIX2 +#ifdef MODE_MINIX3 +#define GRUB_MINIX_MAGIC 0x4D5A +#elif defined(MODE_MINIX2) #define GRUB_MINIX_MAGIC 0x2468 #define GRUB_MINIX_MAGIC_30 0x2478 #else #define GRUB_MINIX_MAGIC 0x137F #define GRUB_MINIX_MAGIC_30 0x138F #endif -#define GRUB_MINIX_BSIZE 1024U + +#define GRUB_MINIX_INODE_DIR_BLOCKS 7 #define GRUB_MINIX_LOG2_BSIZE 1 #define GRUB_MINIX_ROOT_INODE 1 #define GRUB_MINIX_MAX_SYMLNK_CNT 8 @@ -41,7 +44,7 @@ #define GRUB_MINIX_IFDIR 0040000U #define GRUB_MINIX_IFLNK 0120000U -#ifdef MODE_MINIX2 +#if defined(MODE_MINIX2) || defined(MODE_MINIX3) typedef grub_uint32_t grub_minix_uintn_t; #define grub_minix_le_to_cpu_n grub_le_to_cpu32 #else @@ -50,6 +53,13 @@ typedef grub_uint16_t grub_minix_uintn_t; #endif #define GRUB_MINIX_INODE_BLKSZ(data) sizeof (grub_minix_uintn_t) +#ifdef MODE_MINIX3 +typedef grub_uint32_t grub_minix_ino_t; +#define grub_minix_le_to_cpu_ino grub_le_to_cpu32 +#else +typedef grub_uint16_t grub_minix_ino_t; +#define grub_minix_le_to_cpu_ino grub_le_to_cpu16 +#endif #define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size)) #define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode)) @@ -62,9 +72,28 @@ typedef grub_uint16_t grub_minix_uintn_t; #define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \ + grub_le_to_cpu16 (sblock->log2_zone_size)) -#define GRUB_MINIX_ZONESZ (GRUB_MINIX_BSIZE \ +#define GRUB_MINIX_ZONESZ (data->block_size \ << grub_le_to_cpu16 (sblock->log2_zone_size)) +#ifdef MODE_MINIX3 +struct grub_minix_sblock +{ + grub_uint32_t inode_cnt; + grub_uint16_t zone_cnt; + grub_uint16_t inode_bmap_size; + grub_uint16_t zone_bmap_size; + grub_uint16_t first_data_zone; + grub_uint16_t log2_zone_size; + grub_uint16_t pad; + grub_uint32_t max_file_size; + grub_uint32_t zones; + grub_uint16_t magic; + + grub_uint16_t pad2; + grub_uint16_t block_size; + grub_uint8_t disk_version; +}; +#else struct grub_minix_sblock { grub_uint16_t inode_cnt; @@ -76,8 +105,28 @@ struct grub_minix_sblock grub_uint32_t max_file_size; grub_uint16_t magic; }; +#endif -#ifndef MODE_MINIX2 +#if defined(MODE_MINIX3) + +struct grub_minix_inode +{ + grub_uint16_t mode; + grub_uint16_t nlinks; + grub_uint16_t uid; + grub_uint8_t gid; + grub_uint8_t pad; + grub_uint32_t size; + grub_uint32_t atime; + grub_uint32_t mtime; + grub_uint32_t ctime; + grub_uint32_t dir_zones[7]; + grub_uint32_t indir_zone; + grub_uint32_t double_indir_zone; + grub_uint32_t unused; +}; + +#elif defined(MODE_MINIX2) struct grub_minix_inode { grub_uint16_t mode; @@ -121,6 +170,7 @@ struct grub_minix_data int linknest; grub_disk_t disk; int filename_size; + grub_size_t block_size; }; static grub_dl_t my_mod; @@ -141,18 +191,22 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) { grub_minix_uintn_t indirn; grub_disk_read (data->disk, +#ifdef MODE_MINIX3 + zone * (data->block_size / GRUB_DISK_SECTOR_SIZE), +#else zone << GRUB_MINIX_LOG2_ZONESZ, +#endif sizeof (grub_minix_uintn_t) * num, sizeof (grub_minix_uintn_t), (char *) &indirn); return grub_minix_le_to_cpu_n (indirn); } /* Direct block. */ - if (blk < 7) + if (blk < GRUB_MINIX_INODE_DIR_BLOCKS) return GRUB_MINIX_INODE_DIR_ZONES (data, blk); /* Indirect block. */ - blk -= 7; + blk -= GRUB_MINIX_INODE_DIR_BLOCKS; if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)) { indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk); @@ -185,25 +239,27 @@ static grub_ssize_t grub_minix_read_file (struct grub_minix_data *data, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_disk_addr_t len, char *buf) + grub_off_t pos, grub_disk_addr_t len, char *buf) { struct grub_minix_sblock *sblock = &data->sblock; - int i; - int blockcnt; + grub_disk_addr_t i; + grub_disk_addr_t blockcnt; + grub_uint64_t posblock; + grub_uint32_t blockoff; /* Adjust len so it we can't read past the end of the file. */ if (len + pos > GRUB_MINIX_INODE_SIZE (data)) len = GRUB_MINIX_INODE_SIZE (data) - pos; - blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE; + blockcnt = grub_divmod64 ((len + pos + data->block_size - 1), + data->block_size, 0); + posblock = grub_divmod64 (pos, data->block_size, &blockoff); - for (i = pos / GRUB_MINIX_BSIZE; i < blockcnt; i++) + for (i = posblock; i < blockcnt; i++) { - int blknr; - int blockoff = pos % GRUB_MINIX_BSIZE; - int blockend = GRUB_MINIX_BSIZE; - - int skipfirst = 0; + grub_disk_addr_t blknr; + grub_uint32_t blockend = data->block_size; + grub_off_t skipfirst = 0; blknr = grub_minix_get_file_block (data, i); if (grub_errno) @@ -212,28 +268,32 @@ grub_minix_read_file (struct grub_minix_data *data, /* Last block. */ if (i == blockcnt - 1) { - blockend = (len + pos) % GRUB_MINIX_BSIZE; + grub_divmod64 (len + pos, data->block_size, &blockend); if (!blockend) - blockend = GRUB_MINIX_BSIZE; + blockend = data->block_size; } /* First block. */ - if (i == (pos / (int) GRUB_MINIX_BSIZE)) + if (i == posblock) { skipfirst = blockoff; blockend -= skipfirst; } data->disk->read_hook = read_hook; - grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ, + grub_disk_read (data->disk, +#ifdef MODE_MINIX3 + blknr * (sblock->block_size / GRUB_DISK_SECTOR_SIZE), +#else + blknr << GRUB_MINIX_LOG2_ZONESZ, +#endif skipfirst, blockend, buf); - data->disk->read_hook = 0; if (grub_errno) return -1; - buf += GRUB_MINIX_BSIZE - skipfirst; + buf += data->block_size - skipfirst; } return len; @@ -248,16 +308,18 @@ grub_minix_read_inode (struct grub_minix_data *data, int ino) struct grub_minix_sblock *sblock = &data->sblock; /* Block in which the inode is stored. */ - int block; + grub_disk_addr_t block; data->ino = ino; /* The first inode in minix is inode 1. */ ino--; - - block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size) - + grub_le_to_cpu16 (sblock->zone_bmap_size)) - << GRUB_MINIX_LOG2_BSIZE); - + block = (2 + grub_le_to_cpu16 (sblock->inode_bmap_size) + + grub_le_to_cpu16 (sblock->zone_bmap_size)); +#ifndef MODE_MINIX3 + block <<= GRUB_MINIX_LOG2_BSIZE; +#else + block *= sblock->block_size / GRUB_DISK_SECTOR_SIZE; +#endif block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode)); int offs = (ino % (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode)) @@ -333,7 +395,7 @@ grub_minix_find_file (struct grub_minix_data *data, const char *path) do { - grub_uint16_t ino; + grub_minix_ino_t ino; char filename[data->filename_size + 1]; if (grub_strlen (name) == 0) @@ -353,7 +415,7 @@ grub_minix_find_file (struct grub_minix_data *data, const char *path) if (!grub_strcmp (name, filename)) { dirino = data->ino; - grub_minix_read_inode (data, grub_le_to_cpu16 (ino)); + grub_minix_read_inode (data, grub_minix_le_to_cpu_ino (ino)); /* Follow the symlink. */ if ((GRUB_MINIX_INODE_MODE (data) @@ -409,20 +471,35 @@ grub_minix_mount (grub_disk_t disk) goto fail; if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC) + { +#if !defined(MODE_MINIX3) data->filename_size = 14; +#else + data->filename_size = 60; +#endif + } +#if !defined(MODE_MINIX3) else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30) data->filename_size = 30; +#endif else goto fail; data->disk = disk; data->linknest = 0; +#ifdef MODE_MINIX3 + data->block_size = grub_le_to_cpu16 (data->sblock.block_size); +#else + data->block_size = 1024U; +#endif return data; fail: grub_free (data); -#ifdef MODE_MINIX2 +#if defined(MODE_MINIX3) + grub_error (GRUB_ERR_BAD_FS, "not a minix3 filesystem"); +#elif defined(MODE_MINIX2) grub_error (GRUB_ERR_BAD_FS, "not a minix2 filesystem"); #else grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem"); @@ -458,7 +535,7 @@ grub_minix_dir (grub_device_t device, const char *path, while (pos < GRUB_MINIX_INODE_SIZE (data)) { - grub_uint16_t ino; + grub_minix_ino_t ino; char filename[data->filename_size + 1]; int dirino = data->ino; struct grub_dirhook_info info; @@ -474,10 +551,13 @@ grub_minix_dir (grub_device_t device, const char *path, (char *) filename) < 0) return grub_errno; filename[data->filename_size] = '\0'; + if (!ino) + { + pos += sizeof (ino) + data->filename_size; + continue; + } - /* The filetype is not stored in the dirent. Read the inode to - find out the filetype. This *REALLY* sucks. */ - grub_minix_read_inode (data, grub_le_to_cpu16 (ino)); + grub_minix_read_inode (data, grub_minix_le_to_cpu_ino (ino)); info.dir = ((GRUB_MINIX_INODE_MODE (data) & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR); if (hook (filename, &info) ? 1 : 0) @@ -556,7 +636,9 @@ grub_minix_close (grub_file_t file) static struct grub_fs grub_minix_fs = { -#ifdef MODE_MINIX2 +#if defined(MODE_MINIX3) + .name = "minix3", +#elif defined(MODE_MINIX2) .name = "minix2", #else .name = "minix", @@ -568,7 +650,9 @@ static struct grub_fs grub_minix_fs = .next = 0 }; -#ifdef MODE_MINIX2 +#if defined(MODE_MINIX3) +GRUB_MOD_INIT(minix3) +#elif defined(MODE_MINIX2) GRUB_MOD_INIT(minix2) #else GRUB_MOD_INIT(minix) @@ -578,7 +662,9 @@ GRUB_MOD_INIT(minix) my_mod = mod; } -#ifdef MODE_MINIX2 +#if defined(MODE_MINIX3) +GRUB_MOD_FINI(minix3) +#elif defined(MODE_MINIX2) GRUB_MOD_FINI(minix2) #else GRUB_MOD_FINI(minix) diff --git a/grub-core/fs/minix3.c b/grub-core/fs/minix3.c new file mode 100644 index 000000000..58a21d2b5 --- /dev/null +++ b/grub-core/fs/minix3.c @@ -0,0 +1,2 @@ +#define MODE_MINIX3 1 +#include "minix.c" From 58ee1408a8be7d386027882cb07e14f76a2b6cfb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 08:53:28 +0200 Subject: [PATCH 122/211] Fix an error in minix inode declaration --- grub-core/fs/minix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index c93dfe085..877f71921 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -126,7 +126,7 @@ struct grub_minix_inode grub_uint32_t unused; }; -#elif defined(MODE_MINIX2) +#elif !defined(MODE_MINIX2) struct grub_minix_inode { grub_uint16_t mode; From 65f01628e19d04be6cad0242d3056dbb656a54b2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 08:56:42 +0200 Subject: [PATCH 123/211] unify minix3 and minix2 inode declarations --- grub-core/fs/minix.c | 49 +++++++++++++------------------------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 877f71921..a01ee77ca 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -107,41 +107,7 @@ struct grub_minix_sblock }; #endif -#if defined(MODE_MINIX3) - -struct grub_minix_inode -{ - grub_uint16_t mode; - grub_uint16_t nlinks; - grub_uint16_t uid; - grub_uint8_t gid; - grub_uint8_t pad; - grub_uint32_t size; - grub_uint32_t atime; - grub_uint32_t mtime; - grub_uint32_t ctime; - grub_uint32_t dir_zones[7]; - grub_uint32_t indir_zone; - grub_uint32_t double_indir_zone; - grub_uint32_t unused; -}; - -#elif !defined(MODE_MINIX2) -struct grub_minix_inode -{ - grub_uint16_t mode; - grub_uint16_t uid; - grub_uint16_t size; - grub_uint32_t ctime; - grub_uint8_t gid; - grub_uint8_t nlinks; - grub_uint16_t dir_zones[7]; - grub_uint16_t indir_zone; - grub_uint16_t double_indir_zone; -}; - -#else - +#if defined(MODE_MINIX3) || defined(MODE_MINIX2) struct grub_minix_inode { grub_uint16_t mode; @@ -158,6 +124,19 @@ struct grub_minix_inode grub_uint32_t unused; }; +#else +struct grub_minix_inode +{ + grub_uint16_t mode; + grub_uint16_t uid; + grub_uint16_t size; + grub_uint32_t ctime; + grub_uint8_t gid; + grub_uint8_t nlinks; + grub_uint16_t dir_zones[7]; + grub_uint16_t indir_zone; + grub_uint16_t double_indir_zone; +}; #endif From 8fc88523dd88ed4e7852bbab28faa8225cde7f21 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 14:09:02 +0200 Subject: [PATCH 124/211] Add minix3 to util filesystems --- Makefile.util.def | 1 + grub-core/fs/minix.c | 36 +++++++++++++++--------------------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 303baea3f..678e581e6 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -60,6 +60,7 @@ library = { common = grub-core/fs/jfs.c; common = grub-core/fs/minix.c; common = grub-core/fs/minix2.c; + common = grub-core/fs/minix3.c; common = grub-core/fs/nilfs2.c; common = grub-core/fs/ntfs.c; common = grub-core/fs/ntfscomp.c; diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index a01ee77ca..298eef394 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -70,10 +70,19 @@ typedef grub_uint16_t grub_minix_ino_t; #define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_le_to_cpu_n \ (data->inode.double_indir_zone)) +#ifndef MODE_MINIX3 #define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \ - + grub_le_to_cpu16 (sblock->log2_zone_size)) + + grub_le_to_cpu16 (data->sblock.log2_zone_size)) +#endif #define GRUB_MINIX_ZONESZ (data->block_size \ - << grub_le_to_cpu16 (sblock->log2_zone_size)) + << grub_le_to_cpu16 (data->sblock.log2_zone_size)) + +#ifdef MODE_MINIX3 +#define GRUB_MINIX_ZONE2SECT(zone) ((zone) * (data->block_size / GRUB_DISK_SECTOR_SIZE)) +#else +#define GRUB_MINIX_ZONE2SECT(zone) ((zone) << GRUB_MINIX_LOG2_ZONESZ) +#endif + #ifdef MODE_MINIX3 struct grub_minix_sblock @@ -160,7 +169,6 @@ static grub_err_t grub_minix_find_file (struct grub_minix_data *data, static int grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) { - struct grub_minix_sblock *sblock = &data->sblock; int indir; auto int grub_get_indir (int, int); @@ -170,11 +178,7 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) { grub_minix_uintn_t indirn; grub_disk_read (data->disk, -#ifdef MODE_MINIX3 - zone * (data->block_size / GRUB_DISK_SECTOR_SIZE), -#else - zone << GRUB_MINIX_LOG2_ZONESZ, -#endif + GRUB_MINIX_ZONE2SECT(zone), sizeof (grub_minix_uintn_t) * num, sizeof (grub_minix_uintn_t), (char *) &indirn); return grub_minix_le_to_cpu_n (indirn); @@ -220,7 +224,6 @@ grub_minix_read_file (struct grub_minix_data *data, unsigned offset, unsigned length), grub_off_t pos, grub_disk_addr_t len, char *buf) { - struct grub_minix_sblock *sblock = &data->sblock; grub_disk_addr_t i; grub_disk_addr_t blockcnt; grub_uint64_t posblock; @@ -262,11 +265,7 @@ grub_minix_read_file (struct grub_minix_data *data, data->disk->read_hook = read_hook; grub_disk_read (data->disk, -#ifdef MODE_MINIX3 - blknr * (sblock->block_size / GRUB_DISK_SECTOR_SIZE), -#else - blknr << GRUB_MINIX_LOG2_ZONESZ, -#endif + GRUB_MINIX_ZONE2SECT(blknr), skipfirst, blockend, buf); data->disk->read_hook = 0; if (grub_errno) @@ -292,13 +291,8 @@ grub_minix_read_inode (struct grub_minix_data *data, int ino) /* The first inode in minix is inode 1. */ ino--; - block = (2 + grub_le_to_cpu16 (sblock->inode_bmap_size) - + grub_le_to_cpu16 (sblock->zone_bmap_size)); -#ifndef MODE_MINIX3 - block <<= GRUB_MINIX_LOG2_BSIZE; -#else - block *= sblock->block_size / GRUB_DISK_SECTOR_SIZE; -#endif + block = GRUB_MINIX_ZONE2SECT (2 + grub_le_to_cpu16 (sblock->inode_bmap_size) + + grub_le_to_cpu16 (sblock->zone_bmap_size)); block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode)); int offs = (ino % (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode)) From cff5e5e58d93bdd028aba1a220bb59a7962bba52 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 21 Apr 2011 10:37:45 +0100 Subject: [PATCH 125/211] grub-core/fs/squash4.c: Add missing GRUB_MOD_LICENSE. --- grub-core/fs/squash4.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 8e8388628..4f1265582 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* object format Pointed by superblock RAW Fixed offset (0) From 5452733f3505fcd1135c3705a9565365be60bfd5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 12:39:08 +0200 Subject: [PATCH 126/211] more or less functional ia64 grub-mkimage --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 1 + grub-core/kern/dl.c | 2 + grub-core/kern/ia64/dl.c | 66 ++----- include/grub/dl.h | 12 +- util/grub-mkimage.c | 29 ++- util/grub-mkimagexx.c | 345 +++++++++++++++++++++++++++++++++--- 7 files changed, 358 insertions(+), 98 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index c37cac965..df3b14138 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -98,6 +98,7 @@ library = { common = grub-core/script/main.c; common = grub-core/script/script.c; common = grub-core/script/argv.c; + common = grub-core/kern/ia64/dl_helper.c; }; program = { diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index c21c38763..7bb51adfe 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -128,6 +128,7 @@ kernel = { ia64_efi = kern/ia64/efi/startup.S; ia64_efi = kern/ia64/efi/init.c; ia64_efi = kern/ia64/dl.c; + ia64_efi = kern/ia64/dl_helper.c; i386_pc = kern/i386/pc/init.c; i386_pc = kern/i386/pc/mmap.c; diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index f871b81a1..aa15cfa24 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -247,6 +247,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) #ifdef __ia64__ grub_arch_dl_get_tramp_got_size (e, &tramp, &got); + tramp *= GRUB_IA64_DL_TRAMP_SIZE; + got *= sizeof (grub_uint64_t); tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN); if (talign < GRUB_ARCH_DL_TRAMP_ALIGN) talign = GRUB_ARCH_DL_TRAMP_ALIGN; diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 9bbebcd2f..0d1e0d2e6 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -54,15 +54,18 @@ add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value) { case 0: p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2); - p->val = (((((p->val >> 2) & MASK20) + value) & MASK20) << 2) | (p->val & ~(MASK20 << 2)); + p->val = ((((((p->val >> 2) & MASK20) + value) & MASK20) << 2) + | (p->val & ~(MASK20 << 2))); break; case 1: p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7); - p->val = (((((p->val >> 3) & MASK20) + value) & MASK20) << 3) | (p->val & ~(MASK20 << 3)); + p->val = ((((((p->val >> 3) & MASK20) + value) & MASK20) << 3) + | (p->val & ~(MASK20 << 3))); break; case 2: p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12); - p->val = (((((p->val >> 4) & MASK20) + value) & MASK20) << 4) | (p->val & ~(MASK20 << 4)); + p->val = ((((((p->val >> 4) & MASK20) + value) & MASK20) << 4) + | (p->val & ~(MASK20 << 4))); break; } } @@ -137,6 +140,8 @@ struct ia64_trampoline static void make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr) { + COMPILE_TIME_ASSERT (sizeof (struct ia64_trampoline) + == GRUB_IA64_DL_TRAMP_SIZE); grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); tr->addr_hi[0] = ((addr & 0xc00000) >> 16); tr->addr_hi[1] = (addr >> 24) & 0xff; @@ -146,60 +151,13 @@ make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr) tr->addr_hi[5] = (addr >> 56) & 0xff; tr->e0 = 0xe0; tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01; - tr->addr_lo[1] = ((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11) | ((addr & 0x200000) >> 17); + tr->addr_lo[1] = (((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11) + | ((addr & 0x200000) >> 17)); tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19); tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60; grub_memcpy (tr->jump, jump, sizeof (tr->jump)); } -void -grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got) -{ - const Elf_Ehdr *e = ehdr; - grub_size_t cntt = 0, cntg = 0;; - const Elf_Shdr *s; - Elf_Word entsize; - unsigned i; - - /* Find a symbol table. */ - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; - - if (i == e->e_shnum) - return; - - entsize = s->sh_entsize; - - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_RELA) - { - Elf_Rela *rel, *max; - - for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; rel++) - switch (ELF_R_TYPE (rel->r_info)) - { - case R_IA64_PCREL21B: - cntt++; - break; - case R_IA64_LTOFF_FPTR22: - case R_IA64_LTOFF22X: - case R_IA64_LTOFF22: - cntg++; - break; - } - } - *tramp = cntt * sizeof (struct ia64_trampoline); - *got = cntg * sizeof (grub_uint64_t); -} - - /* Relocate symbols. */ grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) @@ -279,7 +237,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) } break; case R_IA64_SEGREL64LSB: - *(grub_uint64_t *) addr += value - rel->r_offset; + *(grub_uint64_t *) addr += value - (grub_addr_t) seg->addr; break; case R_IA64_FPTR64LSB: case R_IA64_DIR64LSB: @@ -296,8 +254,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) case R_IA64_LTOFF22X: case R_IA64_LTOFF22: *gpptr = value; - if ((addr & 0xffff) == 0x4301) - grub_dprintf ("modules", "off = %lx\n", (grub_addr_t) gpptr - (grub_addr_t) gp); add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp); gpptr++; break; diff --git a/include/grub/dl.h b/include/grub/dl.h index b45928a76..6646902d4 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -126,12 +126,18 @@ grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); void grub_arch_dl_init_linker (void); #endif -#ifdef __ia64__ -void grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); +#define GRUB_IA64_DL_TRAMP_ALIGN 16 +#define GRUB_IA64_DL_TRAMP_SIZE 48 +#define GRUB_IA64_DL_GOT_ALIGN 16 +void +grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); + +#ifdef __ia64__ #define GRUB_ARCH_DL_TRAMP_ALIGN 16 #define GRUB_ARCH_DL_GOT_ALIGN 16 - +#define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size #else #endif diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 507a7a80d..9f4e2a61f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,13 @@ struct image_target_desc grub_uint16_t pe_target; }; +#define EFI64_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \ + + GRUB_PE32_SIGNATURE_SIZE \ + + sizeof (struct grub_pe32_coff_header) \ + + sizeof (struct grub_pe64_optional_header) \ + + 4 * sizeof (struct grub_pe32_section_table), \ + GRUB_PE32_SECTION_ALIGNMENT) + struct image_target_desc image_targets[] = { { @@ -248,12 +256,7 @@ struct image_target_desc image_targets[] = .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe64_optional_header) - + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT), + .vaddr_offset = EFI64_HEADER_SIZE, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, .pe_target = GRUB_PE32_MACHINE_X86_64, @@ -372,12 +375,7 @@ struct image_target_desc image_targets[] = .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe64_optional_header) - + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT), + .vaddr_offset = EFI64_HEADER_SIZE, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, .pe_target = GRUB_PE32_MACHINE_IA64, @@ -930,12 +928,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], + 4 * sizeof (struct grub_pe32_section_table), GRUB_PE32_SECTION_ALIGNMENT); else - header_size = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe64_optional_header) - + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT); + header_size = EFI64_HEADER_SIZE; reloc_addr = ALIGN_UP (header_size + core_size, image_target->section_align); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index 20cbacf15..6f68bf1af 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -56,6 +56,7 @@ static Elf_Addr SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Shdr *symtab_section, Elf_Addr *section_addresses, Elf_Half section_entsize, Elf_Half num_sections, + void *jumpers, Elf_Addr jumpers_addr, struct image_target_desc *image_target) { Elf_Word symtab_size, sym_size, num_syms; @@ -65,6 +66,7 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Word i; Elf_Shdr *strtab_section; const char *strtab; + grub_uint64_t *jptr = jumpers; strtab_section = (Elf_Shdr *) ((char *) sections @@ -103,6 +105,16 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, sym->st_value = (grub_target_to_host (sym->st_value) + section_addresses[index]); + + if (image_target->elf_target == EM_IA_64 && ELF_ST_TYPE (sym->st_info) + == STT_FUNC) + { + *jptr = sym->st_value; + sym->st_value = (char *) jptr - (char *) jumpers + jumpers_addr; + jptr++; + *jptr = 0; + jptr++; + } grub_util_info ("locating %s at 0x%x", name, sym->st_value, section_addresses[index]); if (! start_address) @@ -134,6 +146,152 @@ SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); } +static Elf_Addr +SUFFIX (count_funcs) (Elf_Ehdr *e, Elf_Shdr *symtab_section, + struct image_target_desc *image_target) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Addr start_address = 0; + Elf_Sym *sym; + Elf_Word i; + int ret = 0; + + symtab_size = grub_target_to_host (symtab_section->sh_size); + sym_size = grub_target_to_host (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host (symtab_section->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + ret++; + + return ret; +} + +#ifdef MKIMAGE_ELF64 +struct unaligned_uint32 +{ + grub_uint32_t val; +} __attribute__ ((packed)); + +#define MASK20 ((1 << 20) - 1) +#define MASK19 ((1 << 19) - 1) + +static void +add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value) +{ + struct unaligned_uint32 *p; + switch (addr & 3) + { + case 0: + p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2); + p->val = ((((((p->val >> 2) & MASK20) + value) & MASK20) << 2) + | (p->val & ~(MASK20 << 2))); + break; + case 1: + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7); + p->val = ((((((p->val >> 3) & MASK20) + value) & MASK20) << 3) + | (p->val & ~(MASK20 << 3))); + break; + case 2: + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12); + p->val = ((((((p->val >> 4) & MASK20) + value) & MASK20) << 4) + | (p->val & ~(MASK20 << 4))); + break; + } +} + +#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) ) + +static grub_uint32_t +add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value) +{ + grub_uint32_t high, mid, low, c; + low = (a & 0x00007f); + mid = (a & 0x7fc000) >> 7; + high = (a & 0x003e00) << 7; + c = (low | mid | high) + value; + return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00 +} + +static void +add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value) +{ + struct unaligned_uint32 *p; + switch (addr & 3) + { + case 0: + p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2); + p->val = ((add_value_to_slot_21_real (((p->val >> 2) & MASKF21), value) & MASKF21) << 2) | (p->val & ~(MASKF21 << 2)); + break; + case 1: + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7); + p->val = ((add_value_to_slot_21_real (((p->val >> 3) & MASKF21), value) & MASKF21) << 3) | (p->val & ~(MASKF21 << 3)); + break; + case 2: + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12); + p->val = ((add_value_to_slot_21_real (((p->val >> 4) & MASKF21), value) & MASKF21) << 4) | (p->val & ~(MASKF21 << 4)); + break; + } +} + + +struct ia64_kernel_trampoline +{ + /* nop.m */ + grub_uint8_t nop[5]; + /* movl r15 = addr*/ + grub_uint8_t addr_hi[6]; + grub_uint8_t e0; + grub_uint8_t addr_lo[4]; + grub_uint8_t jump[0x20]; +}; + +static grub_uint8_t nopm[5] = + { + /* [MLX] nop.m 0x0 */ + 0x05, 0x00, 0x00, 0x00, 0x01 + }; + +static grub_uint8_t jump[0x20] = + { + /* [MMI] add r15=r15,r1;; */ + 0x0b, 0x78, 0x3c, 0x02, 0x00, 0x20, + /* ld8 r16=[r15],8 */ + 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, + /* mov r14=r1;; */ + 0x01, 0x08, 0x00, 0x84, + /* [MIB] ld8 r1=[r15] */ + 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, + /* mov b6=r16 */ + 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, + /* br.few b6;; */ + 0x60, 0x00, 0x80, 0x00 + }; + +static void +make_trampoline (struct ia64_kernel_trampoline *tr, grub_uint64_t addr) +{ + grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); + tr->addr_hi[0] = ((addr & 0xc00000) >> 16); + tr->addr_hi[1] = (addr >> 24) & 0xff; + tr->addr_hi[2] = (addr >> 32) & 0xff; + tr->addr_hi[3] = (addr >> 40) & 0xff; + tr->addr_hi[4] = (addr >> 48) & 0xff; + tr->addr_hi[5] = (addr >> 56) & 0xff; + tr->e0 = 0xe0; + tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01; + tr->addr_lo[1] = (((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11) + | ((addr & 0x200000) >> 17)); + tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19); + tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60; + grub_memcpy (tr->jump, jump, sizeof (tr->jump)); +} +#endif + /* Deal with relocation information. This function relocates addresses within the virtual address space starting from 0. So only relative addresses can be fully resolved. Absolute addresses must be relocated @@ -142,10 +300,15 @@ static void SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Addr *section_addresses, Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab, struct image_target_desc *image_target) + const char *strtab, + char *pe_target, Elf_Addr tramp_off, + Elf_Addr got_off, + struct image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; + struct ia64_kernel_trampoline *tr = (void *) (pe_target + tramp_off); + grub_uint64_t *gpptr = (void *) (pe_target + got_off); for (i = 0, s = sections; i < num_sections; @@ -274,15 +437,69 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, break; } break; +#ifdef MKIMAGE_ELF64 case EM_IA_64: switch (ELF_R_TYPE (info)) { + case R_IA64_PCREL21B: + { + grub_uint64_t noff; + make_trampoline (tr, addend + sym_addr); + noff = ((char *) tr - (char *) pe_target + - target_section_addr - (offset & ~3) + - image_target->vaddr_offset) >> 4; + tr++; + if (noff & ~MASK19) + grub_util_error ("trampoline offset too big (%lx)", + noff); + add_value_to_slot_20b ((grub_addr_t) target, noff); + } + break; + + case R_IA64_LTOFF_FPTR22: + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + *gpptr = grub_host_to_target64 (addend + sym_addr); + add_value_to_slot_21 ((grub_addr_t) target, + (char *) gpptr - (char *) pe_target); + gpptr++; + break; + + case R_IA64_GPREL22: + add_value_to_slot_21 ((grub_addr_t) target, + addend + sym_addr); + break; + case R_IA64_PCREL64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + break; + + case R_IA64_SEGREL64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr - target_section_addr); + break; + case R_IA64_DIR64LSB: + case R_IA64_FPTR64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating a direct entry to 0x%" + PRIxGRUB_UINT64_T " at the offset 0x%x", + *target, offset); + break; + + /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */ + case R_IA64_LDXMOV: + break; + default: grub_util_error ("unknown relocation type 0x%x", - ELF_R_TYPE (info)); + ELF_R_TYPE (info)); break; } break; +#endif default: grub_util_error ("unknown architecture type %d", image_target->elf_target); @@ -329,7 +546,7 @@ SUFFIX (add_fixup_entry) (struct fixup_block_list **cblock, grub_uint16_t type, b->block_size += 2; } } - else if (b->block_size & (8 - 1)) + else while (b->block_size & (8 - 1)) { /* If not aligned with a 32-bit boundary, add a padding entry. */ @@ -391,9 +608,11 @@ static Elf_Addr SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, Elf_Addr *section_addresses, Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab, struct image_target_desc *image_target) + const char *strtab, + Elf_Addr jumpers, grub_size_t njumpers, + struct image_target_desc *image_target) { - Elf_Half i; + unsigned i; Elf_Shdr *s; struct fixup_block_list *lst, *lst0; Elf_Addr current_address = 0; @@ -401,8 +620,7 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); memset (lst, 0, sizeof (*lst) + 2 * 0x1000); - for (i = 0, s = sections; - i < num_sections; + for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) @@ -470,12 +688,56 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, image_target); } break; + case EM_IA_64: + switch (ELF_R_TYPE (info)) + { + case R_IA64_PCREL64LSB: + case R_IA64_LDXMOV: + case R_IA64_PCREL21B: + case R_IA64_LTOFF_FPTR22: + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + case R_IA64_GPREL22: + case R_IA64_SEGREL64LSB: + break; + + case R_IA64_FPTR64LSB: + case R_IA64_DIR64LSB: +#if 1 + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address + = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address, + image_target); + } +#endif + break; + default: + grub_util_error ("unknown relocation type 0x%x", + ELF_R_TYPE (info)); + break; + } + break; default: grub_util_error ("unknown machine type 0x%x", image_target->elf_target); } } } + if (image_target->elf_target == EM_IA_64) + for (i = 0; i < njumpers; i++) + current_address = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_DIR64, + jumpers + 8 * i, + 0, current_address, + image_target); + current_address = SUFFIX (add_fixup_entry) (&lst, 0, 0, 1, current_address, image_target); { @@ -637,7 +899,10 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, Elf_Off section_offset; Elf_Half section_entsize; grub_size_t kernel_size; + grub_size_t ia64jmp_off = 0, ia64_toff = 0, ia64_got_off = 0; + unsigned ia64jmpnum = 0; Elf_Shdr *symtab_section; + grub_size_t got = 0; *start = 0; @@ -716,23 +981,31 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, break; } +#ifdef MKIMAGE_ELF64 + if (image_target->elf_target == EM_IA_64) + { + grub_size_t tramp; + + *kernel_sz = ALIGN_UP (*kernel_sz, 16); + + grub_ia64_dl_get_tramp_got_size (e, &tramp, &got); + tramp *= sizeof (struct ia64_kernel_trampoline); + + ia64_toff = *kernel_sz; + *kernel_sz += ALIGN_UP (tramp, 16); + + ia64jmp_off = *kernel_sz; + ia64jmpnum = SUFFIX (count_funcs) (e, symtab_section, + image_target); + *kernel_sz += 16 * ia64jmpnum; + + ia64_got_off = *kernel_sz; + *kernel_sz += ALIGN_UP (got * sizeof (grub_uint64_t), 16); + } +#endif + if (! symtab_section) grub_util_error ("no symbol table"); - - *start = SUFFIX (relocate_symbols) (e, sections, symtab_section, - section_vaddresses, section_entsize, - num_sections, image_target); - if (*start == 0) - grub_util_error ("start symbol is not defined"); - - /* Resolve addresses in the virtual address space. */ - SUFFIX (relocate_addresses) (e, sections, section_addresses, section_entsize, - num_sections, strtab, image_target); - - *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section, - section_vaddresses, sections, - section_entsize, num_sections, - strtab, image_target); } else { @@ -742,6 +1015,34 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, out_img = xmalloc (*kernel_sz + total_module_size); + if (image_target->id == IMAGE_EFI) + { + *start = SUFFIX (relocate_symbols) (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections, + (char *) out_img + ia64jmp_off, + ia64jmp_off + + image_target->vaddr_offset, + image_target); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + SUFFIX (relocate_addresses) (e, sections, section_addresses, + section_entsize, + num_sections, strtab, + out_img, ia64_toff, ia64_got_off, + image_target); + + *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab, ia64jmp_off + + image_target->vaddr_offset, + 2 * ia64jmpnum + got, + image_target); + } + for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) From ad6e5cf25fb3cc4a42dcf1eeb2e555ac9300cf91 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 12:42:08 +0200 Subject: [PATCH 127/211] add missing file --- grub-core/kern/ia64/dl_helper.c | 73 +++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 grub-core/kern/ia64/dl_helper.c diff --git a/grub-core/kern/ia64/dl_helper.c b/grub-core/kern/ia64/dl_helper.c new file mode 100644 index 000000000..9503c49ea --- /dev/null +++ b/grub-core/kern/ia64/dl_helper.c @@ -0,0 +1,73 @@ +/* dl.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +void +grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got) +{ + const Elf_Ehdr *e = ehdr; + grub_size_t cntt = 0, cntg = 0;; + const Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + + /* Find a symbol table. */ + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return; + + entsize = s->sh_entsize; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + Elf_Rela *rel, *max; + + for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; rel++) + switch (ELF_R_TYPE (rel->r_info)) + { + case R_IA64_PCREL21B: + cntt++; + break; + case R_IA64_LTOFF_FPTR22: + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + cntg++; + break; + } + } + *tramp = cntt; + *got = cntg; +} + From a988e7aa63948b2e624c1aff8cb63f32d0cee406 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 14:33:30 +0200 Subject: [PATCH 128/211] Fix 2 incorrect vaddr_offsets --- util/grub-mkimagexx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index 6f68bf1af..9bfb5de75 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -446,8 +446,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, grub_uint64_t noff; make_trampoline (tr, addend + sym_addr); noff = ((char *) tr - (char *) pe_target - - target_section_addr - (offset & ~3) - - image_target->vaddr_offset) >> 4; + - target_section_addr - (offset & ~3)) >> 4; tr++; if (noff & ~MASK19) grub_util_error ("trampoline offset too big (%lx)", @@ -461,7 +460,8 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, case R_IA64_LTOFF22: *gpptr = grub_host_to_target64 (addend + sym_addr); add_value_to_slot_21 ((grub_addr_t) target, - (char *) gpptr - (char *) pe_target); + (char *) gpptr - (char *) pe_target + + image_target->vaddr_offset); gpptr++; break; From 7216a1bff3a513549525787b67bd365e8f788569 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 17:05:47 +0200 Subject: [PATCH 129/211] Set EFI ticks to 1000Hz simplifying much of the code and avoiding cotsly division --- grub-core/Makefile.core.def | 1 - grub-core/kern/efi/efi.c | 16 +++++++++++----- include/grub/efi/time.h | 3 +-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7bb51adfe..bc7ce5fbe 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -83,7 +83,6 @@ kernel = { noemu_nodist = symlist.c; i386_pc = kern/generic/rtc_get_time_ms.c; - efi = kern/generic/rtc_get_time_ms.c; i386_qemu = kern/generic/rtc_get_time_ms.c; i386_coreboot = kern/generic/rtc_get_time_ms.c; i386_multiboot = kern/generic/rtc_get_time_ms.c; diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index fa1d0c730..c95058733 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -193,8 +194,8 @@ grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed"); } -grub_uint32_t -grub_get_rtc (void) +grub_uint64_t +grub_rtc_get_time_ms (void) { grub_efi_time_t time; grub_efi_runtime_services_t *r; @@ -204,9 +205,14 @@ grub_get_rtc (void) /* What is possible in this case? */ return 0; - return (((time.minute * 60 + time.second) * 1000 - + time.nanosecond / 1000000) - * GRUB_TICKS_PER_SECOND / 1000); + return ((time.minute * 60 + time.second) * 1000 + + time.nanosecond / 1000000); +} + +grub_uint32_t +grub_get_rtc (void) +{ + return grub_rtc_get_time_ms (); } /* Search the mods section from the PE32/PE32+ image. This code uses diff --git a/include/grub/efi/time.h b/include/grub/efi/time.h index 540f6fc04..51b337309 100644 --- a/include/grub/efi/time.h +++ b/include/grub/efi/time.h @@ -21,8 +21,7 @@ #include -/* This is destined to overflow when one hour passes by. */ -#define GRUB_TICKS_PER_SECOND ((1UL << 31) / 60 / 60 * 2) +#define GRUB_TICKS_PER_SECOND 1000 /* Return the real time in ticks. */ grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); From fa610088bafb704ae3a0bfdc5d2040542687ae14 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 17:06:28 +0200 Subject: [PATCH 130/211] Add missing time installation --- grub-core/kern/ia64/efi/init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c index 13a81a66e..6bb4219ac 100644 --- a/grub-core/kern/ia64/efi/init.c +++ b/grub-core/kern/ia64/efi/init.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ void grub_machine_init (void) { grub_efi_init (); + grub_install_get_time_ms (grub_rtc_get_time_ms); } void From 44748f71c043e069dbbd7c3d960102df94c8a505 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 17:06:56 +0200 Subject: [PATCH 131/211] Add explicit byt 0 to workaround a problem with assembler --- grub-core/kern/ia64/efi/startup.S | 1 + 1 file changed, 1 insertion(+) diff --git a/grub-core/kern/ia64/efi/startup.S b/grub-core/kern/ia64/efi/startup.S index fcaf4e189..b5e26a204 100644 --- a/grub-core/kern/ia64/efi/startup.S +++ b/grub-core/kern/ia64/efi/startup.S @@ -45,6 +45,7 @@ _start: . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) + .byte 0 /* to be filled by grub-mkimage */ /* From 2679b7249be860ad19d8d9fa4e0c882e2eed207a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 17:07:40 +0200 Subject: [PATCH 132/211] Fix LTOFF relocation to functions (needed for trampolines) --- grub-core/kern/ia64/dl.c | 4 +++- util/grub-mkimagexx.c | 13 ++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 0d1e0d2e6..3904f73b7 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -250,9 +250,11 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) add_value_to_slot_21 (addr, value - (grub_addr_t) gp); break; - case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + value = *(grub_uint64_t *) sym->st_value + rel->r_addend; + case R_IA64_LTOFF_FPTR22: *gpptr = value; add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp); gpptr++; diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index 9bfb5de75..352291070 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -455,9 +455,20 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, } break; - case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: + { + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host32 (symtab_section->sh_offset) + + ELF_R_SYM (info) * grub_target_to_host32 (symtab_section->sh_entsize)); + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target + + sym->st_value + - image_target->vaddr_offset)); + } + case R_IA64_LTOFF_FPTR22: *gpptr = grub_host_to_target64 (addend + sym_addr); add_value_to_slot_21 ((grub_addr_t) target, (char *) gpptr - (char *) pe_target From 5a0baa09f29fc1ccd5227e00aea8d409024fddfa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 18:28:25 +0200 Subject: [PATCH 133/211] Remove now useless LD script --- grub-core/kern/ia64/efi/elf_ia64_efi.lds | 84 ------------------------ 1 file changed, 84 deletions(-) delete mode 100644 grub-core/kern/ia64/efi/elf_ia64_efi.lds diff --git a/grub-core/kern/ia64/efi/elf_ia64_efi.lds b/grub-core/kern/ia64/efi/elf_ia64_efi.lds deleted file mode 100644 index b6889d4af..000000000 --- a/grub-core/kern/ia64/efi/elf_ia64_efi.lds +++ /dev/null @@ -1,84 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -OUTPUT_FORMAT("elf64-ia64-little") -OUTPUT_ARCH(ia64) -ENTRY(_start) -SECTIONS -{ - . = 0x240; - .text : - { - *(.text) - *(.text.*) - *(.rodata) - *(.rodata.*) - /* Reserve space for the entry point descriptor. */ - . = ALIGN(16); - QUAD(0) - QUAD(0) - } - . = ALIGN(0x20); - .got : - { - *(.got.plt) - *(.got) - . = ALIGN(0x10); - } - .opd : - { - *(.opd) - } - .sdata : - { - *(.srodata) - *(.sdata) - *(.sbss) - *(.scommon) - . = ALIGN(0x10); - } - .data : - { - *(.data*) - *(.dynbss) - *(.bss) - *(COMMON) - . = ALIGN(0x10); - } - .dynamic : { *(.dynamic) } - - . = ALIGN(4096); - .interp : { *(.interp) } - .plt : { *(.plt) } - .rela : - { - *(.rela.text*) - *(.rela.data*) - *(.rela.sdata) - *(.rela.got) - } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - /DISCARD/ : - { - *(.IA_64.unwind*) - *(.IA64.unwind*) - *(.moddeps) - *(.modname) - } -} From 7b58e65f2423311b2224cf54d347a0c33eac09bc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 18:29:37 +0200 Subject: [PATCH 134/211] track function symbols --- grub-core/gensymlist.sh | 10 +++++----- grub-core/kern/dl.c | 22 +++++++++++++--------- include/grub/dl.h | 2 +- include/grub/elf.h | 3 +++ 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/grub-core/gensymlist.sh b/grub-core/gensymlist.sh index 0ab56e9cb..5f402ea87 100644 --- a/grub-core/gensymlist.sh +++ b/grub-core/gensymlist.sh @@ -47,7 +47,7 @@ grub_register_exported_symbols (void) EOF cat < sizeof (tab[0])); for (p = tab; p->name; p++) - grub_dl_register_symbol (p->name, p->addr, 0); + grub_dl_register_symbol (p->name, p->addr, p->isfunc, 0); } EOF diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index aa15cfa24..6353b0d59 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -90,6 +90,7 @@ struct grub_symbol struct grub_symbol *next; const char *name; void *addr; + int isfunc; grub_dl_t mod; /* The module to which this symbol belongs. */ }; typedef struct grub_symbol *grub_symbol_t; @@ -114,21 +115,22 @@ grub_symbol_hash (const char *s) /* Resolve the symbol name NAME and return the address. Return NULL, if not found. */ -static void * +static grub_symbol_t grub_dl_resolve_symbol (const char *name) { grub_symbol_t sym; for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next) if (grub_strcmp (sym->name, name) == 0) - return sym->addr; + return sym; return 0; } /* Register a symbol with the name NAME and the address ADDR. */ grub_err_t -grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod) +grub_dl_register_symbol (const char *name, void *addr, int isfunc, + grub_dl_t mod) { grub_symbol_t sym; unsigned k; @@ -151,6 +153,7 @@ grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod) sym->addr = addr; sym->mod = mod; + sym->isfunc = isfunc; k = grub_symbol_hash (name); sym->next = grub_symtab[k]; @@ -371,17 +374,20 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) /* Resolve a global symbol. */ if (sym->st_name != 0 && sym->st_shndx == 0) { - sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name); - if (! sym->st_value) + grub_symbol_t nsym = grub_dl_resolve_symbol (name); + if (! nsym) return grub_error (GRUB_ERR_BAD_MODULE, "symbol not found: `%s'", name); + sym->st_value = (Elf_Addr) nsym->addr; + if (nsym->isfunc) + sym->st_info = ELF_ST_INFO (bind, STT_FUNC); } else { sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, sym->st_shndx); if (bind != STB_LOCAL) - if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + if (grub_dl_register_symbol (name, (void *) sym->st_value, 0, mod)) return grub_errno; } break; @@ -398,13 +404,11 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) return grub_errno; desc[0] = (void *) sym->st_value; desc[1] = mod->base; - if (grub_dl_register_symbol (name, (void *) desc, mod)) - return grub_errno; sym->st_value = (grub_addr_t) desc; } #endif if (bind != STB_LOCAL) - if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + if (grub_dl_register_symbol (name, (void *) sym->st_value, 1, mod)) return grub_errno; if (grub_strcmp (name, "grub_mod_init") == 0) mod->init = (void (*) (grub_dl_t)) sym->st_value; diff --git a/include/grub/dl.h b/include/grub/dl.h index 6646902d4..319ed5745 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -116,7 +116,7 @@ extern grub_dl_t EXPORT_VAR(grub_dl_head); grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name); grub_err_t grub_dl_register_symbol (const char *name, void *addr, - grub_dl_t mod); + int isfunc, grub_dl_t mod); grub_err_t grub_arch_dl_check_header (void *ehdr); grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); diff --git a/include/grub/elf.h b/include/grub/elf.h index b9401f241..a02b90238 100644 --- a/include/grub/elf.h +++ b/include/grub/elf.h @@ -2348,6 +2348,8 @@ typedef Elf32_Xword Elf_Xword; #define ELF_ST_BIND(val) ELF32_ST_BIND(val) #define ELF_ST_TYPE(val) ELF32_ST_TYPE(val) +#define ELF_ST_INFO(a,b) ELF32_ST_INFO(a,b) + #define ELF_R_SYM(val) ELF32_R_SYM(val) #define ELF_R_TYPE(val) ELF32_R_TYPE(val) #define ELF_R_INFO(sym, type) ELF32_R_INFO(sym, type) @@ -2369,6 +2371,7 @@ typedef Elf64_Xword Elf_Xword; #define ELF_ST_BIND(val) ELF64_ST_BIND (val) #define ELF_ST_TYPE(val) ELF64_ST_TYPE (val) +#define ELF_ST_INFO(a,b) ELF64_ST_INFO(a,b) #define ELF_R_SYM(val) ELF64_R_SYM(val) #define ELF_R_TYPE(val) ELF64_R_TYPE(val) #define ELF_R_INFO(sym, type) ELF64_R_INFO(sym, type) From b868b5105219f202cf158e01198d1b7504f050c8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 20:06:03 +0200 Subject: [PATCH 135/211] remove ia64.moved From 485e1572467c5b0cf29086572e7a40da53292146 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 20:16:25 +0200 Subject: [PATCH 136/211] Remove 2 useless directories From ea75312f31fb83300d1f00b9630b05fd79bb7650 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 May 2011 16:27:09 +0200 Subject: [PATCH 137/211] * util/grub-mkimage.c (main): Explicitely flush and sync the output before closing to ensure that it will be readable by grub-setup. --- ChangeLog | 5 +++++ util/grub-mkimage.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 540e171cc..bec788b3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-09 Vladimir Serbinenko + + * util/grub-mkimage.c (main): Explicitely flush and sync the output + before closing to ensure that it will be readable by grub-setup. + 2011-05-05 Vladimir Serbinenko * grub-core/loader/efi/appleloader.c (MAKE_PIWG_PATH): New macro. diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 2ba351596..b71fb0420 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1609,6 +1609,8 @@ main (int argc, char *argv[]) argv + optind, memdisk, config, image_target, note, comp); + fflush (fp); + fsync (fileno (fp)); fclose (fp); if (dir) From 157effb745b4e520327bde2ac3de131f766da095 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 May 2011 18:46:51 +0200 Subject: [PATCH 138/211] * grub-core/kern/emu/hostdisk.c (linux_find_partition): Prevent possible overflow. --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bec788b3c..532a3a3b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-09 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (linux_find_partition): Prevent possible + overflow. + 2011-05-09 Vladimir Serbinenko * util/grub-mkimage.c (main): Explicitely flush and sync the output diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 63bca37ee..085048e86 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -550,7 +550,7 @@ struct linux_partition_cache struct linux_partition_cache *linux_partition_cache_list; static int -linux_find_partition (char *dev, unsigned long sector) +linux_find_partition (char *dev, grub_disk_addr_t sector) { size_t len = strlen (dev); const char *format; From fa68d99c4552d02be40c56b787141e340021a4ca Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 May 2011 18:48:50 +0200 Subject: [PATCH 139/211] * grub-core/kern/emu/hostdisk.c (open_device): Set data->fd to -1 if openning fails. Reported by: Mark Korenberg. --- ChangeLog | 6 ++++++ grub-core/kern/emu/hostdisk.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 532a3a3b8..7c924a505 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-05-09 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (open_device): Set data->fd to -1 if + openning fails. + Reported by: Mark Korenberg. + 2011-05-09 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (linux_find_partition): Prevent possible diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 085048e86..92882838f 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -678,6 +678,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) } close (data->fd); + data->fd = -1; } /* Open the partition. */ @@ -736,6 +737,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) #endif } close (data->fd); + data->fd = -1; } fd = open (map[disk->id].device, flags); From d8ce9995012629e60c91ed24df01720871558c4f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 May 2011 18:50:25 +0200 Subject: [PATCH 140/211] Fix surname spelling in Changelog --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7c924a505..6da178a9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -348,7 +348,7 @@ (grub_util_biosdisk_open): Don't apply ioctl on non-disk devices. (open_device) Likewise. (grub_util_biosdisk_close): Likewise. - Reported by: Mark Korenberger. + Reported by: Mark Korenberg. 2011-04-10 Alexander Kurtz From dd94a3df9deb3d8fad0950bd3ce180b5a1c262e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 May 2011 18:59:35 +0200 Subject: [PATCH 141/211] * grub-core/kern/emu/hostdisk.c (linux_find_partition): Don't abort on first non-existant partition. --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6da178a9f..5136a915e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-09 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (linux_find_partition): Don't abort + on first non-existant partition. + 2011-05-09 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (open_device): Set data->fd to -1 if diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 92882838f..feb2a8ff5 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -596,7 +596,7 @@ linux_find_partition (char *dev, grub_disk_addr_t sector) fd = open (real_dev, O_RDONLY); if (fd == -1) - return 0; + continue; close (fd); start = find_partition_start (real_dev); From 9c9bfc6de9c1c397e857506ed6410e1f1c379b8d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 May 2011 19:33:03 +0200 Subject: [PATCH 142/211] * grub-core/term/at_keyboard.c (fetch_key): Make a printf on unknown key into a dprintf. --- ChangeLog | 5 +++++ grub-core/term/at_keyboard.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5136a915e..9baad1f9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-09 Vladimir Serbinenko + + * grub-core/term/at_keyboard.c (fetch_key): Make a printf on + unknown key into a dprintf. + 2011-05-09 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (linux_find_partition): Don't abort diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index 210ac21cc..56aa7275e 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -431,11 +431,11 @@ fetch_key (int *is_break) if (!ret) { if (was_ext) - grub_printf ("Unknown key 0xe0+0x%02x from set %d\n", - at_key, current_set); + grub_dprintf ("atkeyb", "Unknown key 0xe0+0x%02x from set %d\n", + at_key, current_set); else - grub_printf ("Unknown key 0x%02x from set %d\n", - at_key, current_set); + grub_dprintf ("atkeyb", "Unknown key 0x%02x from set %d\n", + at_key, current_set); return -1; } return ret; From 52856af26237d211bc413f36b1573d267badad37 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 10 May 2011 09:14:41 +0200 Subject: [PATCH 143/211] * grub-core/loader/efi/chainloader.c (grub_chainloader_unload): Set file_path to 0 for surety. (grub_chainloader_boot): Set exit_data to NULL. Unset the loader once done. (grub_cmd_chainloader): Fix confusing error message if file is empty. --- ChangeLog | 8 ++++++++ grub-core/loader/efi/chainloader.c | 10 ++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9baad1f9c..ed0bc71d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-05-09 Vladimir Serbinenko + + * grub-core/loader/efi/chainloader.c (grub_chainloader_unload): Set + file_path to 0 for surety. + (grub_chainloader_boot): Set exit_data to NULL. + Unset the loader once done. + (grub_cmd_chainloader): Fix confusing error message if file is empty. + 2011-05-09 Vladimir Serbinenko * grub-core/term/at_keyboard.c (fetch_key): Make a printf on diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index 869b64ced..5dd5adab2 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -57,6 +57,7 @@ grub_chainloader_unload (void) grub_free (file_path); grub_free (cmdline); cmdline = 0; + file_path = 0; grub_dl_unref (my_mod); return GRUB_ERR_NONE; @@ -68,7 +69,7 @@ grub_chainloader_boot (void) grub_efi_boot_services_t *b; grub_efi_status_t status; grub_efi_uintn_t exit_data_size; - grub_efi_char16_t *exit_data; + grub_efi_char16_t *exit_data = NULL; b = grub_efi_system_table->boot_services; status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data); @@ -95,7 +96,7 @@ grub_chainloader_boot (void) if (exit_data) efi_call_1 (b->free_pool, exit_data); - grub_chainloader_unload (); + grub_loader_unset (); return grub_errno; } @@ -238,6 +239,11 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), grub_efi_print_device_path (file_path); size = grub_file_size (file); + if (!size) + { + grub_error (GRUB_ERR_BAD_OS, "file is empty"); + goto fail; + } pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12); status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, From 56dbe7b4855d9aa6dc45d0cf5a8a03c28696f864 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 10 May 2011 10:40:22 +0200 Subject: [PATCH 144/211] * util/grub.d/10_linux.in: Correctly handle the Linux in root. --- ChangeLog | 4 ++++ util/grub.d/10_linux.in | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ed0bc71d6..d36d3441f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-05-10 Vladimir Serbinenko + + * util/grub.d/10_linux.in: Correctly handle the Linux in root. + 2011-05-09 Vladimir Serbinenko * grub-core/loader/efi/chainloader.c (grub_chainloader_unload): Set diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 1dbcad90c..3c3a2a5d5 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -98,10 +98,17 @@ EOF EOF fi - if [ -z "${prepare_boot_cache}" ]; then - prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" + if [ x$dirname = x/ ]; then + if [ -z "${prepare_root_cache}" ]; then + prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/")" + fi + printf '%s\n' "${prepare_root_cache}" + else + if [ -z "${prepare_boot_cache}" ]; then + prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" + fi + printf '%s\n' "${prepare_boot_cache}" fi - printf '%s\n' "${prepare_boot_cache}" message="$(gettext_printf "Loading Linux %s ..." ${version})" cat << EOF echo '$message' @@ -131,6 +138,7 @@ case x`uname -m` in esac prepare_boot_cache= +prepare_root_cache= while [ "x$list" != "x" ] ; do linux=`version_find_latest $list` From 9b44fecaa65643896bfd95fc76a5a782b802e416 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 15:17:02 +0200 Subject: [PATCH 145/211] * grub-core/kern/mips/dl.c (grub_arch_dl_relocate_symbols): Handle R_MIPS_JALR since it's used by newer compiler. --- ChangeLog | 5 +++++ grub-core/kern/mips/dl.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index d36d3441f..944fcb4ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-13 Vladimir Serbinenko + + * grub-core/kern/mips/dl.c (grub_arch_dl_relocate_symbols): Handle + R_MIPS_JALR since it's used by newer compiler. + 2011-05-10 Vladimir Serbinenko * util/grub.d/10_linux.in: Correctly handle the Linux in root. diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c index 485955e7f..e17e9f30b 100644 --- a/grub-core/kern/mips/dl.c +++ b/grub-core/kern/mips/dl.c @@ -213,6 +213,8 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) = sizeof (grub_uint32_t) * (gpptr - gp); gpptr++; break; + case R_MIPS_JALR: + break; default: { grub_free (gp); From a298aa046c528b8c4a5a73fb5dd92d24bdd453f6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 15:20:16 +0200 Subject: [PATCH 146/211] * grub-core/boot/mips/startup_raw.S: Use jalr rather than bal to call grub_decompress_core since later would fail if grub_decompress_core is too far. --- ChangeLog | 6 ++++++ grub-core/boot/mips/startup_raw.S | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 944fcb4ab..d1a1d6f05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-05-13 Vladimir Serbinenko + + * grub-core/boot/mips/startup_raw.S: Use jalr rather than bal to call + grub_decompress_core since later would fail if grub_decompress_core + is too far. + 2011-05-13 Vladimir Serbinenko * grub-core/kern/mips/dl.c (grub_arch_dl_relocate_symbols): Handle diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index c41ce8257..2e874e251 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -170,9 +170,11 @@ argdone: */ move $s6, $a3 - lui $sp, %hi(_start - 256) + lui $t0, %hi(EXT_C(grub_decompress_core)) + addiu $t0, $t0, %lo(EXT_C(grub_decompress_core)) - bal EXT_C(grub_decompress_core) + lui $sp, %hi(_start - 256) + jalr $t0 addiu $sp, $sp, %lo(_start - 256) move $a0, $s1 From 60ddfad3dab5c5eb479227d287f83ee66f67ebe4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 15:35:06 +0200 Subject: [PATCH 147/211] * grub-core/boot/mips/startup_raw.S: Flush cache after loading decompressor. --- ChangeLog | 5 +++++ grub-core/boot/mips/startup_raw.S | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index d1a1d6f05..ede161faf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-13 Vladimir Serbinenko + + * grub-core/boot/mips/startup_raw.S: Flush cache after loading + decompressor. + 2011-05-13 Vladimir Serbinenko * grub-core/boot/mips/startup_raw.S: Use jalr rather than bal to call diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index 2e874e251..6ba04c12f 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -150,6 +150,13 @@ argdone: b 1b addiu $t1, $t1, 1 2: + lui $a0, %hi(base) + addiu $a0, $a0, %lo(base) + lui $a1, %hi(_end) + addiu $a1, %lo(_end) + subu $a1,$a1,$a0 + +#include "../../kern/mips/cache_flush.S" /* Decompress the payload. */ lui $a0, %hi(__bss_start) From 11d86592b7bec1c7ffa746bb1bf384b3cfa7953b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 15:38:42 +0200 Subject: [PATCH 148/211] Adjust mips/dl.c for bigendian --- grub-core/kern/mips/dl.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c index e17e9f30b..e4ce12157 100644 --- a/grub-core/kern/mips/dl.c +++ b/grub-core/kern/mips/dl.c @@ -34,7 +34,7 @@ grub_arch_dl_check_header (void *ehdr) Elf_Ehdr *e = ehdr; /* Check the magic numbers. */ -#ifdef WORDS_BIGENDIAN +#ifdef GRUB_CPU_WORDS_BIGENDIAN if (e->e_ident[EI_CLASS] != ELFCLASS32 || e->e_ident[EI_DATA] != ELFDATA2MSB || e->e_machine != EM_MIPS) @@ -144,14 +144,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) rel < max; rel++) { - Elf_Word *addr; + grub_uint8_t *addr; Elf_Sym *sym; if (seg->size < rel->r_offset) return grub_error (GRUB_ERR_BAD_MODULE, "reloc offset is out of the segment"); - addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); + addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset); sym = (Elf_Sym *) ((char *) mod->symtab + entsize * ELF_R_SYM (rel->r_info)); if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy) @@ -163,7 +163,11 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) { grub_uint32_t value; Elf_Rel *rel2; - + +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + /* Handle partner lo16 relocation. Lower part is treated as signed. Hence add 0x8000 to compensate. */ @@ -175,13 +179,20 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) && ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16) { value += *(grub_int16_t *) - ((char *) seg->addr + rel2->r_offset); + ((char *) seg->addr + rel2->r_offset +#ifdef GRUB_CPU_WORDS_BIGENDIAN + + 2 +#endif + ); break; } *(grub_uint16_t *) addr = (value >> 16) & 0xffff; } break; case R_MIPS_LO16: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif *(grub_uint16_t *) addr += (sym->st_value) & 0xffff; break; case R_MIPS_32: @@ -208,6 +219,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) case R_MIPS_GOT16: case R_MIPS_CALL16: /* FIXME: reuse*/ +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif *gpptr = sym->st_value + *(grub_uint16_t *) addr; *(grub_uint16_t *) addr = sizeof (grub_uint32_t) * (gpptr - gp); From 8906c3dd40f9a0fa64bc91f32b42f3078a57323b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 16:36:05 +0200 Subject: [PATCH 149/211] sgi support --- conf/Makefile.common | 2 +- configure.ac | 3 + gentpl.py | 8 +- grub-core/Makefile.am | 10 +- grub-core/Makefile.core.def | 45 +++- grub-core/commands/arc/lsdev.c | 53 ++++ grub-core/disk/arc/arcdisk.c | 232 +++++++++++++++++ grub-core/kern/mips/arc/init.c | 203 +++++++++++++++ grub-core/kern/mips/init.c | 18 ++ grub-core/kern/mips/yeeloong/init.c | 17 +- grub-core/lib/arc/datetime.c | 48 ++++ grub-core/mmap/mips/{yeeloong => }/uppermem.c | 2 +- grub-core/partmap/dvh.c | 124 +++++++++ grub-core/term/arc/console.c | 123 +++++++++ grub-core/term/terminfo.c | 19 +- include/grub/arc/arc.h | 244 ++++++++++++++++++ include/grub/arc/console.h | 31 +++ include/grub/disk.h | 3 +- include/grub/mips/arc/kernel.h | 2 + include/grub/mips/arc/memory.h | 42 +++ include/grub/mips/arc/time.h | 0 include/grub/mips/kernel.h | 30 +++ include/grub/mips/loongson.h | 7 +- include/grub/mips/memory.h | 61 ++++- include/grub/mips/mips.h | 30 +++ include/grub/mips/time.h | 33 ++- include/grub/mips/yeeloong/kernel.h | 32 +-- include/grub/mips/yeeloong/memory.h | 34 +-- include/grub/mips/yeeloong/time.h | 12 +- include/grub/offsets.h | 12 + util/grub-mkimage.c | 93 ++++++- 31 files changed, 1453 insertions(+), 120 deletions(-) create mode 100644 grub-core/commands/arc/lsdev.c create mode 100644 grub-core/disk/arc/arcdisk.c create mode 100644 grub-core/kern/mips/arc/init.c create mode 100644 grub-core/lib/arc/datetime.c rename grub-core/mmap/mips/{yeeloong => }/uppermem.c (98%) create mode 100644 grub-core/partmap/dvh.c create mode 100644 grub-core/term/arc/console.c create mode 100644 include/grub/arc/arc.h create mode 100644 include/grub/arc/console.h create mode 100644 include/grub/mips/arc/kernel.h create mode 100644 include/grub/mips/arc/memory.h create mode 100644 include/grub/mips/arc/time.h create mode 100644 include/grub/mips/kernel.h create mode 100644 include/grub/mips/mips.h diff --git a/conf/Makefile.common b/conf/Makefile.common index 5aa13cdd6..13963d5f3 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -28,10 +28,10 @@ endif if COND_mips_yeeloong CFLAGS_PLATFORM += -mexplicit-relocs CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK - CCASFLAGS_PLATFORM = -march=mips3 endif if COND_mips CFLAGS_PLATFORM += -mflush-func=grub_cpu_flush_cache + CCASFLAGS_PLATFORM = -march=mips3 endif if COND_sparc64_ieee1275 CFLAGS_PLATFORM += -mno-app-regs diff --git a/configure.ac b/configure.ac index 811bd992d..28c13b511 100644 --- a/configure.ac +++ b/configure.ac @@ -124,6 +124,7 @@ case "$target_cpu"-"$platform" in sparc64-ieee1275) ;; mips-qemu-mips) ;; mips-yeeloong) ;; + mips-arc) ;; *-emu) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; esac @@ -158,6 +159,7 @@ case "$platform" in emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; yeeloong) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; qemu-mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; + mips-arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_ARC=1 -DGRUB_MACHINE_ARC=1" ;; esac case "$target_cpu" in mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;; @@ -952,6 +954,7 @@ AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) AM_CONDITIONAL([COND_mips_yeeloong], [test x$target_cpu = xmips -a x$platform = xyeeloong]) AM_CONDITIONAL([COND_mips_qemu_mips], [test x$target_cpu = xmips -a x$platform = xqemu_mips]) +AM_CONDITIONAL([COND_mips_arc], [test x$target_cpu = xmips -a x$platform = xarc]) AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips]) diff --git a/gentpl.py b/gentpl.py index a42a60667..c8d81cfba 100644 --- a/gentpl.py +++ b/gentpl.py @@ -7,7 +7,7 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275", "x86_64_efi", "mips_yeeloong", "sparc64_ieee1275", - "powerpc_ieee1275" ] + "powerpc_ieee1275", "mips_arc" ] GROUPS = {} @@ -17,7 +17,7 @@ GROUPS["common"] = GRUB_PLATFORMS[:] GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ] GROUPS["x86_64"] = [ "x86_64_efi" ] GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] -GROUPS["mips"] = [ "mips_yeeloong" ] +GROUPS["mips"] = [ "mips_yeeloong", "mips_arc" ] GROUPS["sparc64"] = [ "sparc64_ieee1275" ] GROUPS["powerpc"] = [ "powerpc_ieee1275" ] @@ -30,7 +30,7 @@ GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") # Groups based on hardware features GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_yeeloong"]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi") -GROUPS["pci"] = GROUPS["x86"] + GROUPS["mips"] +GROUPS["pci"] = GROUPS["x86"] + ["mips_yeeloong"] GROUPS["usb"] = GROUPS["pci"] # If gfxterm is main output console integrate it into kernel @@ -39,7 +39,7 @@ GROUPS["videomodules"] = GRUB_PLATFORMS[:]; for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) # Similar for terminfo -GROUPS["terminfoinkernel"] = ["mips_yeeloong"] + GROUPS["ieee1275"]; +GROUPS["terminfoinkernel"] = ["mips_yeeloong", "mips_arc"] + GROUPS["ieee1275"]; GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 94f7f3ffe..234bd3ee8 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -125,9 +125,17 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif +if COND_mips +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h +endif + +if COND_mips_arc +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arc/arc.h +endif + if COND_mips_yeeloong KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index f4d38149d..e27d375c4 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -35,6 +35,7 @@ kernel = { mips_yeeloong_ldflags = '-Wl,-Ttext,0x80200000'; powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; + mips_arc_ldflags = '-Wl,-Ttext,0x8a000000'; mips_yeeloong_cppflags = '-DUSE_ASCII_FAILBACK'; i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; @@ -48,7 +49,7 @@ kernel = { i386_ieee1275_startup = kern/i386/ieee1275/startup.S; i386_coreboot_startup = kern/i386/coreboot/startup.S; i386_multiboot_startup = kern/i386/coreboot/startup.S; - mips_yeeloong_startup = kern/mips/startup.S; + mips_startup = kern/mips/startup.S; sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; @@ -81,7 +82,7 @@ kernel = { i386_qemu = kern/generic/rtc_get_time_ms.c; i386_coreboot = kern/generic/rtc_get_time_ms.c; i386_multiboot = kern/generic/rtc_get_time_ms.c; - mips_yeeloong = kern/generic/rtc_get_time_ms.c; + mips = kern/generic/rtc_get_time_ms.c; ieee1275 = disk/ieee1275/ofdisk.c; ieee1275 = kern/ieee1275/cmain.c; @@ -136,13 +137,18 @@ kernel = { i386_ieee1275 = kern/ieee1275/init.c; + mips = kern/mips/cache.S; + mips = kern/mips/dl.c; + mips = kern/mips/init.c; + + mips_arc = kern/mips/arc/init.c; + mips_arc = term/arc/console.c; + mips_arc = disk/arc/arcdisk.c; + mips_yeeloong = term/ns8250.c; mips_yeeloong = bus/bonito.c; mips_yeeloong = bus/cs5536.c; mips_yeeloong = bus/pci.c; - mips_yeeloong = kern/mips/cache.S; - mips_yeeloong = kern/mips/dl.c; - mips_yeeloong = kern/mips/init.c; mips_yeeloong = kern/mips/yeeloong/init.c; mips_yeeloong = term/at_keyboard.c; mips_yeeloong = term/serial.c; @@ -297,10 +303,12 @@ image = { cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed'; - mips_cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000'; + mips_arc_cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x8a000000'; + mips_yeeloong_cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000'; objcopyflags = '-O binary'; - ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; + mips_yeeloong_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; + mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x89f00000'; ldadd = '-lgcc'; cflags = '-static-libgcc'; enable = mips; @@ -311,10 +319,12 @@ image = { mips = boot/mips/startup_raw.S; common = boot/decompressor/none.c; - mips_cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000'; + mips_arc_cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x8a000000'; + mips_yeeloong_cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000'; objcopyflags = '-O binary'; - ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; + mips_yeeloong_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; + mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x89f00000'; ldadd = '-lgcc'; cflags = '-static-libgcc'; enable = mips; @@ -408,6 +418,13 @@ module = { emu_condition = COND_GRUB_EMU_PCI; }; +module = { + name = lsdev; + common = commands/arc/lsdev.c; + + enable = mips_arc; +}; + library = { name = libgnulib.a; common = gnulib/regex.c; @@ -1117,6 +1134,7 @@ module = { x86_efi = lib/efi/datetime.c; sparc64_ieee1275 = lib/ieee1275/datetime.c; powerpc_ieee1275 = lib/ieee1275/datetime.c; + mips_arc = lib/arc/datetime.c; enable = noemu; }; @@ -1228,10 +1246,10 @@ module = { x86_efi = mmap/efi/mmap.c; - mips_yeeloong = mmap/mips/yeeloong/uppermem.c; + mips = mmap/mips/uppermem.c; enable = x86; - enable = mips_yeeloong; + enable = mips; }; module = { @@ -1305,6 +1323,11 @@ module = { common = partmap/sun.c; }; +module = { + name = part_dvh; + common = partmap/dvh.c; +}; + module = { name = part_bsd; common = partmap/bsdlabel.c; diff --git a/grub-core/commands/arc/lsdev.c b/grub-core/commands/arc/lsdev.c new file mode 100644 index 000000000..5d4b0cd09 --- /dev/null +++ b/grub-core/commands/arc/lsdev.c @@ -0,0 +1,53 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_err_t +grub_cmd_lsdev (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + auto int hook (const char *name, const struct grub_arc_component *comp); + int hook (const char *name, const struct grub_arc_component *comp __attribute__ ((unused))) + { + grub_printf ("%s\n", name); + return 0; + } + grub_arc_iterate_devs (hook, 0); + return 0; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(lsdev) +{ + cmd = grub_register_command ("lsdev", grub_cmd_lsdev, "", + N_("List devices.")); +} + +GRUB_MOD_FINI(lsdev) +{ + grub_unregister_command (cmd); +} diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c new file mode 100644 index 000000000..c3b98a52e --- /dev/null +++ b/grub-core/disk/arc/arcdisk.c @@ -0,0 +1,232 @@ +/* ofdisk.c - Open Firmware disk access. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static unsigned last_handle = 0; +static char *last_path = NULL; + +static int +grub_arcdisk_iterate (int (*hook_in) (const char *name)) +{ + auto int hook (const char *name, const struct grub_arc_component *comp); + int hook (const char *name, const struct grub_arc_component *comp) + { + if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK + || comp->type == GRUB_ARC_COMPONENT_TYPE_DISK + || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE)) + return 0; + return hook_in (name); + } + return grub_arc_iterate_devs (hook, 1); +} + +#define RAW_SUFFIX "partition(10)" + +static grub_err_t +reopen (const char *name) +{ + unsigned handle; + + if (last_path && grub_strcmp (last_path, name) == 0) + { + grub_dprintf ("arcdisk", "using already opened %s\n", name); + return GRUB_ERR_NONE; + } + if (GRUB_ARC_FIRMWARE_VECTOR->open (name, 0, &handle)) + { + grub_dprintf ("arcdisk", "couldn't open %s\n", name); + return grub_error (GRUB_ERR_IO, "couldn't open %s", name); + } + if (last_path) + { + GRUB_ARC_FIRMWARE_VECTOR->close (last_handle); + grub_free (last_path); + last_path = NULL; + last_handle = 0; + } + last_path = grub_strdup (name); + if (!last_path) + return grub_errno; + last_handle = handle; + grub_dprintf ("arcdisk", "opened %s\n", name); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_arcdisk_open (const char *name, grub_disk_t disk) +{ + char *fullname, *optr; + const char *iptr; + int state = 0; + grub_err_t err; + int r; + struct grub_arc_fileinfo info; + if (grub_memcmp (name, "arc/", 4) != 0) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not arc device"); + fullname = grub_malloc (2 * grub_strlen (name) + sizeof (RAW_SUFFIX)); + if (!fullname) + return grub_errno; + optr = fullname; + for (iptr = name + 4; *iptr; iptr++) + if (state == 0) + { + if (!grub_isdigit (*iptr)) + *optr++ = *iptr; + else + { + *optr++ = '('; + *optr++ = *iptr; + state = 1; + } + } + else + { + if (grub_isdigit (*iptr)) + *optr++ = *iptr; + else + { + *optr++ = ')'; + state = 0; + } + } + if (state) + *optr++ = ')'; + grub_memcpy (optr, RAW_SUFFIX, sizeof (RAW_SUFFIX)); + disk->data = fullname; + grub_dprintf ("arcdisk", "opening %s\n", fullname); + err = reopen (fullname); + if (err) + return err; + + r = GRUB_ARC_FIRMWARE_VECTOR->getfileinformation (last_handle, &info); + if (r) + { + grub_uint64_t res = 0; + int i; + + grub_dprintf ("arcdisk", "couldn't retrieve size: %d\n", r); + for (i = 40; i >= 9; i--) + { + grub_uint64_t pos = res | (1ULL << i); + char buf[512]; + long unsigned count = 0; + grub_dprintf ("arcdisk", + "seek to 0x%" PRIxGRUB_UINT64_T "\n", pos); + if (GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0)) + continue; + if (GRUB_ARC_FIRMWARE_VECTOR->read (last_handle, buf, + 0x200, &count)) + continue; + if (count == 0) + continue; + res |= (1ULL << i); + } + grub_dprintf ("arcdisk", + "determined disk size 0x%" PRIxGRUB_UINT64_T "\n", res); + disk->total_sectors = (res + 0x200) >> 9; + } + else + disk->total_sectors = (info.end >> 9); + disk->id = 0; /* XXX */ + return GRUB_ERR_NONE; +} + +static void +grub_arcdisk_close (grub_disk_t disk) +{ + grub_free (disk->data); +} + +static grub_err_t +grub_arcdisk_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_err_t err; + grub_uint64_t pos = sector << 9; + unsigned long count; + grub_uint64_t totl = size << 9; + int r; + + err = reopen (disk->data); + if (err) + return err; + r = GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0); + if (r) + { + grub_dprintf ("arcdisk", "seek to 0x%" PRIxGRUB_UINT64_T " failed: %d\n", + pos, r); + return grub_error (GRUB_ERR_IO, "couldn't seek"); + } + + while (totl) + { + if (GRUB_ARC_FIRMWARE_VECTOR->read (last_handle, buf, + totl, &count)) + return grub_error (GRUB_ERR_READ_ERROR, "read failed"); + totl -= count; + buf += count; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_arcdisk_write (grub_disk_t disk __attribute ((unused)), + grub_disk_addr_t sector __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) +{ + return GRUB_ERR_NOT_IMPLEMENTED_YET; +} + +static struct grub_disk_dev grub_arcdisk_dev = + { + .name = "arcdisk", + .id = GRUB_DISK_DEVICE_ARCDISK_ID, + .iterate = grub_arcdisk_iterate, + .open = grub_arcdisk_open, + .close = grub_arcdisk_close, + .read = grub_arcdisk_read, + .write = grub_arcdisk_write, + .next = 0 + }; + +void +grub_arcdisk_init (void) +{ + grub_disk_dev_register (&grub_arcdisk_dev); +} + +void +grub_arcdisk_fini (void) +{ + if (last_path) + { + GRUB_ARC_FIRMWARE_VECTOR->close (last_handle); + grub_free (last_path); + last_path = NULL; + last_handle = 0; + } + + grub_disk_dev_unregister (&grub_arcdisk_dev); +} diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c new file mode 100644 index 000000000..85d8b26f5 --- /dev/null +++ b/grub-core/kern/mips/arc/init.c @@ -0,0 +1,203 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *type_names[] = { +#ifdef GRUB_CPU_WORDS_BIGENDIAN + NULL, +#endif + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "eisa", "tc", "scsi", "dti", "multi", "disk", "tape", "cdrom", "worm", + "serial", "net", "video", "par", "point", "key", "audio", "other", + "rdisk", "fdisk", "tape", "modem", "monitor", "print", "pointer", + "keyboard", "term", "other", "line", "network", NULL +}; + +static int +iterate_rec (const char *prefix, const struct grub_arc_component *parent, + int (*hook) (const char *name, + const struct grub_arc_component *comp), + int alt_names) +{ + const struct grub_arc_component *comp; + FOR_ARC_CHILDREN(comp, parent) + { + char *name; + const char *cname = NULL; + if (comp->type < ARRAY_SIZE (type_names)) + cname = type_names[comp->type]; + if (!cname) + cname = "unknown"; + if (alt_names) + name = grub_xasprintf ("%s/%s%d", prefix, cname, comp->key); + else + name = grub_xasprintf ("%s%s(%d)", prefix, cname, comp->key); + if (!name) + return 1; + if (hook (name, comp)) + { + grub_free (name); + return 1; + } + if (iterate_rec ((parent ? name : prefix), comp, hook, alt_names)) + { + grub_free (name); + return 1; + } + grub_free (name); + } + return 0; +} + +int +grub_arc_iterate_devs (int (*hook) (const char *name, + const struct grub_arc_component *comp), + int alt_names) +{ + return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, alt_names); +} + +grub_err_t +grub_machine_mmap_iterate (grub_memory_hook_t hook) +{ + struct grub_arc_memory_descriptor *cur = NULL; + while (1) + { + grub_memory_type_t type; + cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur); + if (!cur) + return GRUB_ERR_NONE; + switch (cur->type) + { + case GRUB_ARC_MEMORY_EXCEPTION_BLOCK: + case GRUB_ARC_MEMORY_SYSTEM_PARAMETER_BLOCK: + case GRUB_ARC_MEMORY_FW_PERMANENT: + default: + type = GRUB_MEMORY_RESERVED; + break; + + case GRUB_ARC_MEMORY_FW_TEMPORARY: + case GRUB_ARC_MEMORY_FREE: + case GRUB_ARC_MEMORY_LOADED: + case GRUB_ARC_MEMORY_FREE_CONTIGUOUS: + type = GRUB_MEMORY_AVAILABLE; + break; + case GRUB_ARC_MEMORY_BADRAM: + type = GRUB_MEMORY_BADRAM; + break; + } + if (hook (((grub_uint64_t) cur->start_page) << 12, + ((grub_uint64_t) cur->num_pages) << 12, type)) + return GRUB_ERR_NONE; + } +} + +void +grub_machine_init (void) +{ + struct grub_arc_memory_descriptor *cur = NULL; + + grub_console_init_early (); + + /* FIXME: measure this. */ + grub_arch_cpuclock = 64000000; + grub_install_get_time_ms (grub_rtc_get_time_ms); + + while (1) + { + grub_uint64_t start, end; + cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur); + if (!cur) + break; + if (cur->type != GRUB_ARC_MEMORY_FREE + && cur->type != GRUB_ARC_MEMORY_LOADED + && cur->type != GRUB_ARC_MEMORY_FREE_CONTIGUOUS) + continue; + start = ((grub_uint64_t) cur->start_page) << 12; + end = ((grub_uint64_t) cur->num_pages) << 12; + end += start; + if ((grub_uint64_t) end > (GRUB_KERNEL_MIPS_ARC_LINK_ADDR & 0x1fffffff)) + end = (GRUB_KERNEL_MIPS_ARC_LINK_ADDR & 0x1fffffff); + if (end > start) + grub_mm_init_region ((void *) (grub_addr_t) (start | 0x80000000), + end - start); + } + + grub_console_init_lately (); + + grub_arcdisk_init (); +} + +void +grub_machine_fini (void) +{ +} + +void +grub_halt (void) +{ + GRUB_ARC_FIRMWARE_VECTOR->powerdown (); + + grub_millisleep (1500); + + grub_printf ("Shutdown failed\n"); + grub_refresh (); + while (1); +} + +void +grub_exit (void) +{ + GRUB_ARC_FIRMWARE_VECTOR->exit (); + + grub_millisleep (1500); + + grub_printf ("Exit failed\n"); + grub_refresh (); + while (1); +} + +void +grub_reboot (void) +{ + GRUB_ARC_FIRMWARE_VECTOR->restart (); + + grub_millisleep (1500); + + grub_printf ("Reboot failed\n"); + grub_refresh (); + while (1); +} + diff --git a/grub-core/kern/mips/init.c b/grub-core/kern/mips/init.c index f220108d4..3b08d5606 100644 --- a/grub-core/kern/mips/init.c +++ b/grub-core/kern/mips/init.c @@ -18,6 +18,24 @@ #include #include +#include +#include + +/* FIXME: use interrupt to count high. */ +grub_uint64_t +grub_get_rtc (void) +{ + static grub_uint32_t high = 0; + static grub_uint32_t last = 0; + grub_uint32_t low; + + asm volatile ("mfc0 %0, " GRUB_CPU_MIPS_COP0_TIMER_COUNT : "=r" (low)); + if (low < last) + high++; + last = low; + + return (((grub_uint64_t) high) << 32) | low; +} void grub_machine_set_prefix (void) diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/yeeloong/init.c index 7a48d69f5..426e7eabb 100644 --- a/grub-core/kern/mips/yeeloong/init.c +++ b/grub-core/kern/mips/yeeloong/init.c @@ -31,6 +31,7 @@ #include #include #include +#include extern void grub_video_sm712_init (void); extern void grub_video_init (void); @@ -43,22 +44,6 @@ extern void grub_terminfo_init (void); extern void grub_keylayouts_init (void); extern void grub_boot_init (void); -/* FIXME: use interrupt to count high. */ -grub_uint64_t -grub_get_rtc (void) -{ - static grub_uint32_t high = 0; - static grub_uint32_t last = 0; - grub_uint32_t low; - - asm volatile ("mfc0 %0, " GRUB_CPU_LOONGSON_COP0_TIMER_COUNT : "=r" (low)); - if (low < last) - high++; - last = low; - - return (((grub_uint64_t) high) << 32) | low; -} - grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook) { diff --git a/grub-core/lib/arc/datetime.c b/grub-core/lib/arc/datetime.c new file mode 100644 index 000000000..b8d910e5f --- /dev/null +++ b/grub-core/lib/arc/datetime.c @@ -0,0 +1,48 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +grub_err_t +grub_get_datetime (struct grub_datetime *datetime) +{ + struct grub_arc_timeinfo *dt; + grub_memset (datetime, 0, sizeof (*datetime)); + + dt = GRUB_ARC_FIRMWARE_VECTOR->gettime (); + + datetime->year = dt->y; + datetime->month = dt->m; + datetime->day = dt->d; + datetime->hour = dt->h; + datetime->minute = dt->min; + datetime->second = dt->s; + + return 0; +} + +grub_err_t +grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused))) +{ + return grub_error (GRUB_ERR_IO, "setting time isn't supported"); +} diff --git a/grub-core/mmap/mips/yeeloong/uppermem.c b/grub-core/mmap/mips/uppermem.c similarity index 98% rename from grub-core/mmap/mips/yeeloong/uppermem.c rename to grub-core/mmap/mips/uppermem.c index 723b6a888..832618540 100644 --- a/grub-core/mmap/mips/yeeloong/uppermem.c +++ b/grub-core/mmap/mips/uppermem.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include grub_uint64_t grub_mmap_get_lower (void) diff --git a/grub-core/partmap/dvh.c b/grub-core/partmap/dvh.c new file mode 100644 index 000000000..118401612 --- /dev/null +++ b/grub-core/partmap/dvh.c @@ -0,0 +1,124 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define DVH_MAGIC 0x0be5a941 + +struct grub_dvh_partition_descriptor +{ + grub_uint32_t length; + grub_uint32_t start; + grub_uint32_t type; +} __attribute__ ((packed)); + +struct grub_dvh_block +{ + grub_uint32_t magic; + grub_uint8_t unused[308]; + struct grub_dvh_partition_descriptor parts[16]; + grub_uint32_t checksum; + grub_uint32_t unused2; +} __attribute__ ((packed)); + +static struct grub_partition_map grub_dvh_partition_map; + +/* Verify checksum (true=ok). */ +static int +grub_dvh_is_valid (struct grub_dvh_block *label) +{ + grub_uint32_t *pos; + grub_uint32_t sum = 0; + + for (pos = (grub_uint32_t *) label; + pos < (grub_uint32_t *) (label + 1); + pos++) + sum += *pos; + + return ! sum; +} + +static grub_err_t +dvh_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition p; + struct grub_dvh_block block; + unsigned partnum; + grub_err_t err; + + p.partmap = &grub_dvh_partition_map; + err = grub_disk_read (disk, 0, 0, sizeof (struct grub_dvh_block), + &block); + if (err) + return err; + + if (DVH_MAGIC != grub_be_to_cpu32 (block.magic)) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a dvh partition table"); + + if (! grub_dvh_is_valid (&block)) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum"); + + /* Maybe another error value would be better, because partition + table _is_ recognized but invalid. */ + for (partnum = 0; partnum < ARRAY_SIZE (block.parts); partnum++) + { + if (block.parts[partnum].length == 0) + continue; + + if (partnum == 10) + continue; + + p.start = grub_be_to_cpu32 (block.parts[partnum].start); + p.len = grub_be_to_cpu32 (block.parts[partnum].length); + p.number = p.index = partnum; + if (hook (disk, &p)) + break; + } + + return grub_errno; +} + + +/* Partition map type. */ +static struct grub_partition_map grub_dvh_partition_map = + { + .name = "dvh", + .iterate = dvh_partition_map_iterate, + }; + +GRUB_MOD_INIT(part_dvh) +{ + grub_partition_map_register (&grub_dvh_partition_map); +} + +GRUB_MOD_FINI(part_dvh) +{ + grub_partition_map_unregister (&grub_dvh_partition_map); +} + diff --git a/grub-core/term/arc/console.c b/grub-core/term/arc/console.c new file mode 100644 index 000000000..b7e428795 --- /dev/null +++ b/grub-core/term/arc/console.c @@ -0,0 +1,123 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* FIXME: use unicode. */ + +static int +readkey (struct grub_term_input *term __attribute__ ((unused))) +{ + unsigned long count; + char chr; + + if (GRUB_ARC_FIRMWARE_VECTOR->get_read_status (GRUB_ARC_STDIN)) + return -1; + + if (GRUB_ARC_FIRMWARE_VECTOR->read (GRUB_ARC_STDIN, &chr, 1, &count)) + return -1; + if (!count) + return -1; + return chr; +} + +static void +put (struct grub_term_output *term __attribute__ ((unused)), const int c) +{ + unsigned long count; + char chr = c; + + GRUB_ARC_FIRMWARE_VECTOR->write (GRUB_ARC_STDOUT, &chr, 1, &count); +} + +static struct grub_terminfo_output_state grub_console_terminfo_output; + +static grub_err_t +grub_console_init_output (struct grub_term_output *term) +{ + struct grub_arc_display_status *info = NULL; + if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length + >= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus + 1) + - (char *) GRUB_ARC_FIRMWARE_VECTOR) + && GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus) + info = GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus (GRUB_ARC_STDOUT); + if (info) + { + grub_console_terminfo_output.width = info->w; + grub_console_terminfo_output.height = info->h; + } + grub_terminfo_output_init (term); + + return 0; +} + +static struct grub_terminfo_input_state grub_console_terminfo_input = + { + .readkey = readkey + }; + +static struct grub_terminfo_output_state grub_console_terminfo_output = + { + .put = put, + .width = 80, + .height = 36 + }; + +static struct grub_term_input grub_console_term_input = + { + .name = "console", + .init = grub_terminfo_input_init, + .getkey = grub_terminfo_getkey, + .data = &grub_console_terminfo_input + }; + +static struct grub_term_output grub_console_term_output = + { + .name = "console", + .init = grub_console_init_output, + .putchar = grub_terminfo_putchar, + .getxy = grub_terminfo_getxy, + .getwh = grub_terminfo_getwh, + .gotoxy = grub_terminfo_gotoxy, + .cls = grub_terminfo_cls, + .setcolorstate = grub_terminfo_setcolorstate, + .setcursor = grub_terminfo_setcursor, + .flags = GRUB_TERM_CODE_TYPE_ASCII, + .data = &grub_console_terminfo_output, + .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, + .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + }; + +void +grub_console_init_early (void) +{ + grub_term_register_input ("console", &grub_console_term_input); + grub_term_register_output ("console", &grub_console_term_output); +} + +void grub_terminfo_init (void); + +void +grub_console_init_lately (void) +{ + grub_terminfo_init (); + grub_terminfo_output_register (&grub_console_term_output, "arc"); +} diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index 16158139d..3ba630b33 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -36,6 +36,9 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#define ANSI_C0 0x9b +#define ANSI_C0_STR "\x9b" + static struct grub_term_output *terminfo_outputs; /* Get current terminfo name. */ @@ -123,6 +126,20 @@ grub_terminfo_set_current (struct grub_term_output *term, return grub_errno; } + if (grub_strcmp ("arc", str) == 0) + { + data->name = grub_strdup ("arc"); + data->gotoxy = grub_strdup (ANSI_C0_STR "%i%p1%d;%p2%dH"); + data->cls = grub_strdup (ANSI_C0_STR "2J"); + data->reverse_video_on = grub_strdup (ANSI_C0_STR "7m"); + data->reverse_video_off = grub_strdup (ANSI_C0_STR "0m"); + data->cursor_on = 0; + data->cursor_off = 0; + data->setcolor = grub_strdup (ANSI_C0_STR "3%p1%dm" + ANSI_C0_STR "4%p2%dm"); + return grub_errno; + } + if (grub_strcmp ("ieee1275", str) == 0) { data->name = grub_strdup ("ieee1275"); @@ -369,8 +386,6 @@ grub_terminfo_getwh (struct grub_term_output *term) return (data->width << 8) | data->height; } -#define ANSI_C0 0x9b - static void grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, int (*readkey) (struct grub_term_input *term)) diff --git a/include/grub/arc/arc.h b/include/grub/arc/arc.h new file mode 100644 index 000000000..5ff0a41f1 --- /dev/null +++ b/include/grub/arc/arc.h @@ -0,0 +1,244 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ARC_HEADER +#define GRUB_ARC_HEADER 1 + +#include +#include + +struct grub_arc_memory_descriptor +{ + grub_uint32_t type; + grub_uint32_t start_page; + grub_uint32_t num_pages; +}; + +enum grub_arc_memory_type + { + GRUB_ARC_MEMORY_EXCEPTION_BLOCK, + GRUB_ARC_MEMORY_SYSTEM_PARAMETER_BLOCK, +#ifdef GRUB_CPU_WORDS_BIGENDIAN + GRUB_ARC_MEMORY_FREE_CONTIGUOUS, +#endif + GRUB_ARC_MEMORY_FREE, + GRUB_ARC_MEMORY_BADRAM, + GRUB_ARC_MEMORY_LOADED, GRUB_ARC_MEMORY_FW_TEMPORARY, + GRUB_ARC_MEMORY_FW_PERMANENT, +#ifndef GRUB_CPU_WORDS_BIGENDIAN + GRUB_ARC_MEMORY_FREE_CONTIGUOUS, +#endif + } grub_arc_memory_type_t; + +struct grub_arc_timeinfo +{ + grub_uint16_t y; + grub_uint16_t m; + grub_uint16_t d; + grub_uint16_t h; + grub_uint16_t min; + grub_uint16_t s; + grub_uint16_t ms; +}; + +struct grub_arc_display_status +{ + grub_uint16_t x; + grub_uint16_t y; + grub_uint16_t w; + grub_uint16_t h; + grub_uint8_t fgcolor; + grub_uint8_t bgcolor; + grub_uint8_t high_intensity; + grub_uint8_t underscored; + grub_uint8_t reverse_video; +}; + +struct grub_arc_component +{ + unsigned class; + unsigned type; + unsigned flags; + grub_uint16_t version; + grub_uint16_t rev; + grub_uint32_t key; + grub_uint32_t affinity; + grub_uint32_t configdatasize; + grub_uint32_t idlen; + const char *idstr; +}; + +enum + { +#ifdef GRUB_CPU_WORDS_BIGENDIAN + GRUB_ARC_COMPONENT_TYPE_ARC = 1, +#else + GRUB_ARC_COMPONENT_TYPE_ARC, +#endif + GRUB_ARC_COMPONENT_TYPE_CPU, + GRUB_ARC_COMPONENT_TYPE_FPU, + GRUB_ARC_COMPONENT_TYPE_PRI_I_CACHE, + GRUB_ARC_COMPONENT_TYPE_PRI_D_CACHE, + GRUB_ARC_COMPONENT_TYPE_SEC_I_CACHE, + GRUB_ARC_COMPONENT_TYPE_SEC_D_CACHE, + GRUB_ARC_COMPONENT_TYPE_SEC_CACHE, + GRUB_ARC_COMPONENT_TYPE_EISA, + GRUB_ARC_COMPONENT_TYPE_TCA, + GRUB_ARC_COMPONENT_TYPE_SCSI, + GRUB_ARC_COMPONENT_TYPE_DTIA, + GRUB_ARC_COMPONENT_TYPE_MULTIFUNC, + GRUB_ARC_COMPONENT_TYPE_DISK_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_TAPE_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_CDROM_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_WORM_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_SERIAL_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_NET_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_DISPLAY_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_PARALLEL_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_POINTER_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_KBD_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_AUDIO_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_OTHER_CONTROLLER, + GRUB_ARC_COMPONENT_TYPE_DISK, + GRUB_ARC_COMPONENT_TYPE_FLOPPY, + GRUB_ARC_COMPONENT_TYPE_TAPE, + GRUB_ARC_COMPONENT_TYPE_MODEM, + GRUB_ARC_COMPONENT_TYPE_MONITOR, + GRUB_ARC_COMPONENT_TYPE_PRINTER, + GRUB_ARC_COMPONENT_TYPE_POINTER, + GRUB_ARC_COMPONENT_TYPE_KBD, + GRUB_ARC_COMPONENT_TYPE_TERMINAL, + GRUB_ARC_COMPONENT_TYPE_OTHER_PERIPHERAL, + GRUB_ARC_COMPONENT_TYPE_LINE, + GRUB_ARC_COMPONENT_TYPE_NET, + GRUB_ARC_COMPONENT_TYPE_MEMORY_UNIT, + }; + +struct grub_arc_fileinfo +{ + grub_uint64_t start; + grub_uint64_t end; + grub_uint64_t current; + grub_uint32_t type; + grub_uint32_t fnamelength; + grub_uint8_t attr; + char filename[32]; +}; + +struct grub_arc_firmware_vector +{ + /* 0x00. */ + void *load; + void *invoke; + void *execute; + void *halt; + + /* 0x10. */ + void (*powerdown) (void); + void (*restart) (void); + void (*reboot) (void); + void (*exit) (void); + + /* 0x20. */ + void *reserved1; + const struct grub_arc_component * (*getpeer) (const struct grub_arc_component *comp); + const struct grub_arc_component * (*getchild) (const struct grub_arc_component *comp); + void *getparent; + + /* 0x30. */ + void *getconfigurationdata; + void *addchild; + void *deletecomponent; + void *getcomponent; + + /* 0x40. */ + void *saveconfiguration; + void *getsystemid; + struct grub_arc_memory_descriptor *(*getmemorydescriptor) (struct grub_arc_memory_descriptor *current); + void *reserved2; + + /* 0x50. */ + struct grub_arc_timeinfo *(*gettime) (void); + void *getrelativetime; + void *getdirectoryentry; + int (*open) (const char *path, int mode, unsigned *fileno); + + /* 0x60. */ + int (*close) (unsigned fileno); + int (*read) (unsigned fileno, void *buf, unsigned long n, + unsigned long *count); + int (*get_read_status) (unsigned fileno); + int (*write) (unsigned fileno, void *buf, unsigned long n, + unsigned long *count); + + /* 0x70. */ + int (*seek) (unsigned fileno, grub_uint64_t *pos, int mode); + void *mount; + void *getenvironmentvariable; + void *setenvironmentvariable; + + /* 0x80. */ + int (*getfileinformation) (unsigned fileno, struct grub_arc_fileinfo *info); + void *setfileinformation; + void *flushallcaches; + void *testunicodecharacter; + + /* 0x90. */ + struct grub_arc_display_status * (*getdisplaystatus) (unsigned fileno); +}; + +struct grub_arc_adapter +{ + grub_uint32_t adapter_type; + grub_uint32_t adapter_vector_length; + void *adapter_vector; +}; + +struct grub_arc_system_parameter_block +{ + grub_uint32_t signature; + grub_uint32_t length; + grub_uint16_t version; + grub_uint16_t revision; + void *restartblock; + void *debugblock; + void *gevector; + void *utlbmissvector; + grub_uint32_t firmware_vector_length; + struct grub_arc_firmware_vector *firmwarevector; + grub_uint32_t private_vector_length; + void *private_vector; + grub_uint32_t adapter_count; + struct grub_arc_adapter adapters[0]; +}; + + +#define GRUB_ARC_SYSTEM_PARAMETER_BLOCK ((struct grub_arc_system_parameter_block *) 0xa0001000) +#define GRUB_ARC_FIRMWARE_VECTOR (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmwarevector) +#define GRUB_ARC_STDIN 0 +#define GRUB_ARC_STDOUT 1 + +int EXPORT_FUNC (grub_arc_iterate_devs) (int (*hook) (const char *name, const struct grub_arc_component *comp), int alt_names); + +#define FOR_ARC_CHILDREN(comp, parent) for (comp = GRUB_ARC_FIRMWARE_VECTOR->getchild (parent); comp; comp = GRUB_ARC_FIRMWARE_VECTOR->getpeer (comp)) + +extern void grub_arcdisk_init (void); +extern void grub_arcdisk_fini (void); + + +#endif diff --git a/include/grub/arc/console.h b/include/grub/arc/console.h new file mode 100644 index 000000000..e054f54f5 --- /dev/null +++ b/include/grub/arc/console.h @@ -0,0 +1,31 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CONSOLE_MACHINE_HEADER +#define GRUB_CONSOLE_MACHINE_HEADER 1 + +#include + +/* Initialize the console system. */ +void grub_console_init_early (void); +void grub_console_init_lately (void); + +/* Finish the console system. */ +void grub_console_fini (void); + +#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */ diff --git a/include/grub/disk.h b/include/grub/disk.h index 66db1149a..867283494 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -42,7 +42,8 @@ enum grub_disk_dev_id GRUB_DISK_DEVICE_PXE_ID, GRUB_DISK_DEVICE_SCSI_ID, GRUB_DISK_DEVICE_FILE_ID, - GRUB_DISK_DEVICE_LUKS_ID + GRUB_DISK_DEVICE_LUKS_ID, + GRUB_DISK_DEVICE_ARCDISK_ID, }; struct grub_disk; diff --git a/include/grub/mips/arc/kernel.h b/include/grub/mips/arc/kernel.h new file mode 100644 index 000000000..50694866b --- /dev/null +++ b/include/grub/mips/arc/kernel.h @@ -0,0 +1,2 @@ +#include + diff --git a/include/grub/mips/arc/memory.h b/include/grub/mips/arc/memory.h new file mode 100644 index 000000000..b960d2a37 --- /dev/null +++ b/include/grub/mips/arc/memory.h @@ -0,0 +1,42 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 + +#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x8bfffff0 + +#ifndef ASM_FILE + +static inline grub_err_t +grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + int type __attribute__ ((unused)), + int handle __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} +static inline grub_err_t +grub_machine_mmap_unregister (int handle __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} + +#endif + +#endif diff --git a/include/grub/mips/arc/time.h b/include/grub/mips/arc/time.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h new file mode 100644 index 000000000..d82d0a97d --- /dev/null +++ b/include/grub/mips/kernel.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#include + +#ifndef ASM_FILE + +void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); + +#endif + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h index 6cb1178d5..810b73ef2 100644 --- a/include/grub/mips/loongson.h +++ b/include/grub/mips/loongson.h @@ -19,11 +19,7 @@ #ifndef GRUB_LOONGSON_CPU_HEADER #define GRUB_LOONGSON_CPU_HEADER 1 -#ifdef ASM_FILE -#define GRUB_CPU_REGISTER_WRAP(x) x -#else -#define GRUB_CPU_REGISTER_WRAP(x) #x -#endif +#include #define GRUB_CPU_LOONGSON_FLASH_START 0xbfc00000 #define GRUB_CPU_LOONGSON_FLASH_TLB_REFILL 0xbfc00200 @@ -68,7 +64,6 @@ #define GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE 19 #define GRUB_CPU_LOONGSON_COP0_BADVADDR GRUB_CPU_REGISTER_WRAP($8) -#define GRUB_CPU_LOONGSON_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9) #define GRUB_CPU_LOONGSON_COP0_CAUSE GRUB_CPU_REGISTER_WRAP($13) #define GRUB_CPU_LOONGSON_COP0_EPC GRUB_CPU_REGISTER_WRAP($14) #define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO GRUB_CPU_REGISTER_WRAP($28) diff --git a/include/grub/mips/memory.h b/include/grub/mips/memory.h index e51bcc1f2..2ef2ed31c 100644 --- a/include/grub/mips/memory.h +++ b/include/grub/mips/memory.h @@ -1 +1,60 @@ -#include +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 + +#ifndef ASM_FILE +#include +#include +#include +#endif + +#define GRUB_ARCH_LOWMEMVSTART 0x80000000 +#define GRUB_ARCH_LOWMEMPSTART 0x00000000 +#define GRUB_ARCH_LOWMEMMAXSIZE 0x10000000 +#define GRUB_ARCH_HIGHMEMPSTART 0x10000000 + +#ifndef ASM_FILE + +typedef grub_addr_t grub_phys_addr_t; + +static inline grub_phys_addr_t +grub_vtop (void *a) +{ + return ((grub_phys_addr_t) a) & 0x1fffffff; +} + +static inline void * +grub_map_memory (grub_phys_addr_t a, grub_size_t size __attribute__ ((unused))) +{ + return (void *) (a | 0x80000000); +} + +static inline void +grub_unmap_memory (void *a __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ +} + +grub_uint64_t grub_mmap_get_lower (void); +grub_uint64_t grub_mmap_get_upper (void); + +#endif + +#endif diff --git a/include/grub/mips/mips.h b/include/grub/mips/mips.h new file mode 100644 index 000000000..8c161aa15 --- /dev/null +++ b/include/grub/mips/mips.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_REGISTORS_CPU_HEADER +#define GRUB_REGISTORS_CPU_HEADER 1 + +#ifdef ASM_FILE +#define GRUB_CPU_REGISTER_WRAP(x) x +#else +#define GRUB_CPU_REGISTER_WRAP(x) #x +#endif + +#define GRUB_CPU_MIPS_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9) + +#endif diff --git a/include/grub/mips/time.h b/include/grub/mips/time.h index b143a48e0..1139b24bb 100644 --- a/include/grub/mips/time.h +++ b/include/grub/mips/time.h @@ -1,6 +1,37 @@ -#ifdef GRUB_MACHINE_EMU +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,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 . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +#ifndef GRUB_UTIL + +#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2) + +/* Return the real time in ticks. */ +grub_uint64_t EXPORT_FUNC (grub_get_rtc) (void); + +extern grub_uint32_t EXPORT_VAR (grub_arch_cpuclock); +#endif + static inline void grub_cpu_idle(void) { } + #endif diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h index 15cf9f9fd..7752a3ef5 100644 --- a/include/grub/mips/yeeloong/kernel.h +++ b/include/grub/mips/yeeloong/kernel.h @@ -1,31 +1 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#include - -#ifndef ASM_FILE - -void EXPORT_FUNC (grub_reboot) (void) __attribute__ ((noreturn)); -void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); - -#endif - -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ +#include diff --git a/include/grub/mips/yeeloong/memory.h b/include/grub/mips/yeeloong/memory.h index 9d53b5e0e..4a1065ea5 100644 --- a/include/grub/mips/yeeloong/memory.h +++ b/include/grub/mips/yeeloong/memory.h @@ -19,43 +19,16 @@ #ifndef GRUB_MEMORY_MACHINE_HEADER #define GRUB_MEMORY_MACHINE_HEADER 1 +#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x801ffff0 + #ifndef ASM_FILE #include #include #include #endif -#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x801ffff0 -#define GRUB_ARCH_LOWMEMVSTART 0x80000000 -#define GRUB_ARCH_LOWMEMPSTART 0x00000000 -#define GRUB_ARCH_LOWMEMMAXSIZE 0x10000000 -#define GRUB_ARCH_HIGHMEMPSTART 0x10000000 - #ifndef ASM_FILE -typedef grub_addr_t grub_phys_addr_t; - -static inline grub_phys_addr_t -grub_vtop (void *a) -{ - return ((grub_phys_addr_t) a) & 0x1fffffff; -} - -static inline void * -grub_map_memory (grub_phys_addr_t a, grub_size_t size __attribute__ ((unused))) -{ - return (void *) (a | 0x80000000); -} - -static inline void -grub_unmap_memory (void *a __attribute__ ((unused)), - grub_size_t size __attribute__ ((unused))) -{ -} - -grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate) -(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); - static inline grub_err_t grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), grub_uint64_t size __attribute__ ((unused)), @@ -70,9 +43,6 @@ grub_machine_mmap_unregister (int handle __attribute__ ((unused))) return GRUB_ERR_NONE; } -grub_uint64_t grub_mmap_get_lower (void); -grub_uint64_t grub_mmap_get_upper (void); - extern grub_uint32_t EXPORT_VAR (grub_arch_memsize); extern grub_uint32_t EXPORT_VAR (grub_arch_highmemsize); diff --git a/include/grub/mips/yeeloong/time.h b/include/grub/mips/yeeloong/time.h index 7f468bf12..8b8ee42c4 100644 --- a/include/grub/mips/yeeloong/time.h +++ b/include/grub/mips/yeeloong/time.h @@ -20,18 +20,8 @@ #define KERNEL_MACHINE_TIME_HEADER 1 #include - -#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2) - -/* Return the real time in ticks. */ -grub_uint64_t EXPORT_FUNC (grub_get_rtc) (void); +#include extern grub_uint32_t EXPORT_VAR (grub_arch_busclock); -extern grub_uint32_t EXPORT_VAR (grub_arch_cpuclock); - -static inline void -grub_cpu_idle(void) -{ -} #endif /* ! KERNEL_MACHINE_TIME_HEADER */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 31deb5031..d71e7deae 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -111,6 +111,17 @@ #define GRUB_KERNEL_MIPS_YEELOONG_PREFIX 0x0c #define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END 0x54 +#define GRUB_KERNEL_MIPS_ARC_LINK_ADDR 0x8a000000 + +#define GRUB_KERNEL_MIPS_ARC_LINK_ALIGN 32 + +#define GRUB_KERNEL_MIPS_ARC_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_SIZE 0xc + +#define GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE 0x08 +#define GRUB_KERNEL_MIPS_ARC_PREFIX 0x0c +#define GRUB_KERNEL_MIPS_ARC_PREFIX_END 0x54 + /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_EFI_PREFIX 0x8 @@ -145,6 +156,7 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 #define GRUB_KERNEL_MIPS_YEELOONG_MOD_ALIGN 0x1 +#define GRUB_KERNEL_MIPS_ARC_MOD_ALIGN 0x1 /* Minimal gap between _end and the start of the modules. It's a hack for PowerMac to prevent "CLAIM failed" error. The real fix is to diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index b71fb0420..259d78beb 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -65,7 +65,7 @@ struct image_target_desc IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, - IMAGE_I386_PC_PXE + IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC } id; enum { @@ -355,6 +355,27 @@ struct image_target_desc image_targets[] = .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR }, + { + .name = "mips-arc", + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_MIPS_ARC, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .prefix = GRUB_KERNEL_MIPS_ARC_PREFIX, + .prefix_end = GRUB_KERNEL_MIPS_ARC_PREFIX_END, + .raw_size = 0, + .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, + .compressed_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_MIPS_ARC_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, + .default_compression = COMPRESSION_NONE + }, }; #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) @@ -1217,6 +1238,76 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], core_size = rom_size; } break; + case IMAGE_MIPS_ARC: + { + char *ecoff_img; + struct ecoff_header { + grub_uint16_t magic; + grub_uint16_t nsec; + grub_uint32_t time; + grub_uint32_t syms; + grub_uint32_t nsyms; + grub_uint16_t opt; + grub_uint16_t flags; + grub_uint16_t magic2; + grub_uint16_t version; + grub_uint32_t textsize; + grub_uint32_t datasize; + grub_uint32_t bsssize; + grub_uint32_t entry; + grub_uint32_t text_start; + grub_uint32_t data_start; + grub_uint32_t bss_start; + grub_uint32_t gprmask; + grub_uint32_t cprmask[4]; + grub_uint32_t gp_value; + }; + struct ecoff_section + { + char name[8]; + grub_uint32_t paddr; + grub_uint32_t vaddr; + grub_uint32_t size; + grub_uint32_t file_offset; + grub_uint32_t reloc; + grub_uint32_t gp; + grub_uint16_t nreloc; + grub_uint16_t ngp; + grub_uint32_t flags; + }; + struct ecoff_header *head; + struct ecoff_section *section; + grub_uint32_t target_addr; + size_t program_size; + + program_size = ALIGN_ADDR (core_size); + target_addr = image_target->link_addr - ALIGN_UP(program_size, 1048576) + - (1 << 20); + + ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section)); + grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section)); + head = (void *) ecoff_img; + section = (void *) (head + 1); + head->magic = grub_host_to_target16 (0x160); + head->nsec = grub_host_to_target16 (1); + head->time = grub_host_to_target32 (0); + head->opt = grub_host_to_target16 (0x38); + head->flags = grub_host_to_target16 (0x207); + head->magic2 = grub_host_to_target16 (0x107); + head->textsize = grub_host_to_target32 (program_size); + head->entry = grub_host_to_target32 (target_addr); + head->text_start = grub_host_to_target32 (target_addr); + head->data_start = grub_host_to_target32 (target_addr + program_size); + grub_memcpy (section->name, ".text", sizeof (".text") - 1); + section->vaddr = grub_host_to_target32 (target_addr); + section->size = grub_host_to_target32 (program_size); + section->file_offset = grub_host_to_target32 (sizeof (*head) + sizeof (*section)); + memcpy (section + 1, core_img, core_size); + free (core_img); + core_img = ecoff_img; + core_size = program_size + sizeof (*head) + sizeof (*section); + } + break; case IMAGE_YEELOONG_ELF: case IMAGE_PPC: case IMAGE_COREBOOT: From 12ce749d86fe53bfaee6bce2b552bedcda72bf50 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 16:36:41 +0200 Subject: [PATCH 150/211] sgimips linux loader --- grub-core/loader/mips/linux.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 0bf7b1f8e..0b95bd3c2 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -31,10 +31,12 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* For frequencies. */ -#include #include #ifdef GRUB_MACHINE_MIPS_YEELOONG + +#include + /* This can be detected on runtime from PMON, but: a) it wouldn't work when GRUB is the firmware and @@ -52,7 +54,10 @@ static struct grub_relocator *relocator; static grub_uint8_t *playground; static grub_addr_t target_addr, entry_addr; static int linux_argc; -static grub_off_t argv_off, envp_off; +static grub_off_t argv_off; +#ifdef GRUB_MACHINE_MIPS_YEELOONG +static grub_off_t envp_off; +#endif static grub_off_t rd_addr_arg_off, rd_size_arg_off; static int initrd_loaded = 0; @@ -65,7 +70,12 @@ grub_linux_boot (void) state.gpr[1] = entry_addr; state.gpr[4] = linux_argc; state.gpr[5] = target_addr + argv_off; +#ifdef GRUB_MACHINE_MIPS_YEELOONG state.gpr[6] = target_addr + envp_off; +#else + state.gpr[6] = 0; +#endif + state.gpr[7] = 0; state.jumpreg = 1; grub_relocator32_boot (relocator, state); @@ -200,9 +210,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int i; int size; void *extra = NULL; - grub_uint32_t *linux_argv, *linux_envp; - char *linux_args, *linux_envs; + grub_uint32_t *linux_argv; + char *linux_args; grub_err_t err; +#ifdef GRUB_MACHINE_MIPS_YEELOONG + char *linux_envs; + grub_uint32_t *linux_envp; +#endif if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); @@ -313,6 +327,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), extra = linux_args; +#ifdef GRUB_MACHINE_MIPS_YEELOONG linux_envp = extra; envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground; linux_envs = (char *) (linux_envp + 5); @@ -340,8 +355,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + target_addr; linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); - linux_envp[4] = 0; +#endif grub_loader_set (grub_linux_boot, grub_linux_unload, 1); initrd_loaded = 0; From ae6a81f0bb996aa107810246d4b3148953c95919 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 16:38:23 +0200 Subject: [PATCH 151/211] some additional key sequences for arc --- grub-core/term/terminfo.c | 59 ++++++++++++++++++++++++++++++++++----- include/grub/terminfo.h | 2 +- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index 3ba630b33..3419a5117 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -445,7 +445,8 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, {'K', GRUB_TERM_KEY_END}, {'P', GRUB_TERM_KEY_DC}, {'?', GRUB_TERM_KEY_PPAGE}, - {'/', GRUB_TERM_KEY_NPAGE} + {'/', GRUB_TERM_KEY_NPAGE}, + {'@', GRUB_TERM_KEY_INSERT}, }; static struct @@ -460,6 +461,14 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, {'5', GRUB_TERM_KEY_PPAGE}, {'6', GRUB_TERM_KEY_NPAGE} }; + char fx_key[] = + { 'P', 'Q', 'w', 'x', 't', 'u', + 'q', 'r', 'p', 'M', 'A', 'B' }; + unsigned fx_code[] = + { GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, + GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6, + GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, + GRUB_TERM_KEY_F10, GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12 }; unsigned i; if (c == '\e') @@ -480,17 +489,53 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, return; } - for (i = 0; i < ARRAY_SIZE (four_code_table); i++) - if (four_code_table[i].key == c) + switch (c) + { + case 'O': + CONTINUE_READ; + for (i = 0; i < ARRAY_SIZE (fx_key); i++) + if (fx_key[i] == c) + { + keys[0] = fx_code[i]; + *len = 1; + return; + } + return; + + case '0': { + int num = 0; CONTINUE_READ; - if (c != '~') + if (c != '0' && c != '1') return; - keys[0] = three_code_table[i].ascii; + num = (c - '0') * 10; + CONTINUE_READ; + if (c < '0' || c > '9') + return; + num += (c - '0'); + if (num == 0 || num > 12) + return; + CONTINUE_READ; + if (c != 'q') + return; + keys[0] = fx_code[num - 1]; *len = 1; return; - } - return; + } + + default: + for (i = 0; i < ARRAY_SIZE (four_code_table); i++) + if (four_code_table[i].key == c) + { + CONTINUE_READ; + if (c != '~') + return; + keys[0] = three_code_table[i].ascii; + *len = 1; + return; + } + return; + } } #undef CONTINUE_READ } diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index 5a552b327..e3b28ce88 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -27,7 +27,7 @@ char *EXPORT_FUNC(grub_terminfo_get_current) (struct grub_term_output *term); grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (struct grub_term_output *term, const char *); -#define GRUB_TERMINFO_READKEY_MAX_LEN 4 +#define GRUB_TERMINFO_READKEY_MAX_LEN 6 struct grub_terminfo_input_state { int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN]; From fb25a861086e57e3ab8dbff1f16a5387e5a93d9d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 16:39:02 +0200 Subject: [PATCH 152/211] add dvh to userspace tools --- Makefile.util.def | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.util.def b/Makefile.util.def index 058572f06..50e60f476 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -92,6 +92,7 @@ library = { common = grub-core/partmap/gpt.c; common = grub-core/partmap/msdos.c; common = grub-core/partmap/sun.c; + common = grub-core/partmap/dvh.c; common = grub-core/partmap/sunpc.c; common = grub-core/partmap/bsdlabel.c; common = grub-core/script/function.c; From 214af04cf585007d3b36488b289033c55d4e4719 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 16:41:26 +0200 Subject: [PATCH 153/211] avoid executing cache opcode on non-4 byte aligned boundaries --- grub-core/kern/mips/cache_flush.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grub-core/kern/mips/cache_flush.S b/grub-core/kern/mips/cache_flush.S index 11096c035..a352fd8ba 100644 --- a/grub-core/kern/mips/cache_flush.S +++ b/grub-core/kern/mips/cache_flush.S @@ -9,15 +9,15 @@ subu $t1, $t3, $t2 1: cache 1, 0($t0) - addiu $t1, $t1, 0xffff + addiu $t1, $t1, -0x4 bne $t1, $zero, 1b - addiu $t0, $t0, 0x1 + addiu $t0, $t0, 0x4 sync move $t0, $t2 subu $t1, $t3, $t2 2: cache 0, 0($t0) - addiu $t1, $t1, 0xffff + addiu $t1, $t1, -0x4 bne $t1, $zero, 2b - addiu $t0, $t0, 0x1 + addiu $t0, $t0, 0x4 sync From dd10ec9e60a5e9bc3829e79dc4c7f9b7d8c16593 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 18:02:36 +0200 Subject: [PATCH 154/211] sgimips grub-install partial support (untested) --- util/grub-install.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util/grub-install.in b/util/grub-install.in index ff8bea87c..537830ecb 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -619,6 +619,10 @@ elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${pla exit 1 } fi +elif [ x"${target_cpu}-${platform}" = xmips-arc ]; then + dvhtool -d "${install_device}" --unix-to-vh "{grubdir}/core.${imgext}" grub + echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" + elif [ x"$platform" = xefi ]; then cp "${grubdir}/core.${imgext}" "${efidir}/${efi_file}" # For old macs. Suggested by Peter Jones. From cdcfe2a95fb3a7e4828febab37be2f6ec744e436 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 18:02:58 +0200 Subject: [PATCH 155/211] missing part of previous commits --- grub-core/kern/mips/startup.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index ae0e0b187..48bf253de 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -50,11 +50,11 @@ VARIABLE(grub_prefix) */ . = _start + GRUB_KERNEL_MACHINE_PREFIX_END +VARIABLE (grub_arch_cpuclock) + .long 0 #ifdef GRUB_MACHINE_MIPS_YEELOONG VARIABLE (grub_arch_busclock) .long 0 -VARIABLE (grub_arch_cpuclock) - .long 0 VARIABLE (grub_arch_memsize) .long 0 VARIABLE (grub_arch_highmemsize) From 96a29d188b261ada3cf3085f0edda3a9a5622bfa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 18:03:20 +0200 Subject: [PATCH 156/211] Arc type cleanup --- grub-core/disk/arc/arcdisk.c | 12 ++-- grub-core/kern/mips/arc/init.c | 4 +- include/grub/arc/arc.h | 121 ++++++++++++++++++--------------- 3 files changed, 76 insertions(+), 61 deletions(-) diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c index c3b98a52e..62732c7ad 100644 --- a/grub-core/disk/arc/arcdisk.c +++ b/grub-core/disk/arc/arcdisk.c @@ -22,7 +22,7 @@ #include #include -static unsigned last_handle = 0; +static grub_arc_fileno_t last_handle = 0; static char *last_path = NULL; static int @@ -45,7 +45,7 @@ grub_arcdisk_iterate (int (*hook_in) (const char *name)) static grub_err_t reopen (const char *name) { - unsigned handle; + grub_arc_fileno_t handle; if (last_path && grub_strcmp (last_path, name) == 0) { @@ -79,7 +79,7 @@ grub_arcdisk_open (const char *name, grub_disk_t disk) const char *iptr; int state = 0; grub_err_t err; - int r; + grub_arc_err_t r; struct grub_arc_fileinfo info; if (grub_memcmp (name, "arc/", 4) != 0) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not arc device"); @@ -124,7 +124,7 @@ grub_arcdisk_open (const char *name, grub_disk_t disk) grub_uint64_t res = 0; int i; - grub_dprintf ("arcdisk", "couldn't retrieve size: %d\n", r); + grub_dprintf ("arcdisk", "couldn't retrieve size: %ld\n", r); for (i = 40; i >= 9; i--) { grub_uint64_t pos = res | (1ULL << i); @@ -165,7 +165,7 @@ grub_arcdisk_read (grub_disk_t disk, grub_disk_addr_t sector, grub_uint64_t pos = sector << 9; unsigned long count; grub_uint64_t totl = size << 9; - int r; + grub_arc_err_t r; err = reopen (disk->data); if (err) @@ -173,7 +173,7 @@ grub_arcdisk_read (grub_disk_t disk, grub_disk_addr_t sector, r = GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0); if (r) { - grub_dprintf ("arcdisk", "seek to 0x%" PRIxGRUB_UINT64_T " failed: %d\n", + grub_dprintf ("arcdisk", "seek to 0x%" PRIxGRUB_UINT64_T " failed: %ld\n", pos, r); return grub_error (GRUB_ERR_IO, "couldn't seek"); } diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index 85d8b26f5..8ee965d74 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -61,9 +61,9 @@ iterate_rec (const char *prefix, const struct grub_arc_component *parent, if (!cname) cname = "unknown"; if (alt_names) - name = grub_xasprintf ("%s/%s%d", prefix, cname, comp->key); + name = grub_xasprintf ("%s/%s%lu", prefix, cname, comp->key); else - name = grub_xasprintf ("%s%s(%d)", prefix, cname, comp->key); + name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key); if (!name) return 1; if (hook (name, comp)) diff --git a/include/grub/arc/arc.h b/include/grub/arc/arc.h index 5ff0a41f1..aae73052b 100644 --- a/include/grub/arc/arc.h +++ b/include/grub/arc/arc.h @@ -22,11 +22,21 @@ #include #include +typedef unsigned grub_arc_enum_t; +typedef grub_uint64_t grub_arc_ularge_t; +typedef unsigned long grub_arc_ulong_t; +typedef long grub_arc_long_t; +typedef unsigned short grub_arc_ushort_t; +typedef unsigned char grub_arc_uchar_t; + +typedef grub_arc_long_t grub_arc_err_t; +typedef grub_arc_ulong_t grub_arc_fileno_t; + struct grub_arc_memory_descriptor { - grub_uint32_t type; - grub_uint32_t start_page; - grub_uint32_t num_pages; + grub_arc_enum_t type; + grub_arc_ulong_t start_page; + grub_arc_ulong_t num_pages; }; enum grub_arc_memory_type @@ -47,39 +57,39 @@ enum grub_arc_memory_type struct grub_arc_timeinfo { - grub_uint16_t y; - grub_uint16_t m; - grub_uint16_t d; - grub_uint16_t h; - grub_uint16_t min; - grub_uint16_t s; - grub_uint16_t ms; + grub_arc_ushort_t y; + grub_arc_ushort_t m; + grub_arc_ushort_t d; + grub_arc_ushort_t h; + grub_arc_ushort_t min; + grub_arc_ushort_t s; + grub_arc_ushort_t ms; }; struct grub_arc_display_status { - grub_uint16_t x; - grub_uint16_t y; - grub_uint16_t w; - grub_uint16_t h; - grub_uint8_t fgcolor; - grub_uint8_t bgcolor; - grub_uint8_t high_intensity; - grub_uint8_t underscored; - grub_uint8_t reverse_video; + grub_arc_ushort_t x; + grub_arc_ushort_t y; + grub_arc_ushort_t w; + grub_arc_ushort_t h; + grub_arc_uchar_t fgcolor; + grub_arc_uchar_t bgcolor; + grub_arc_uchar_t high_intensity; + grub_arc_uchar_t underscored; + grub_arc_uchar_t reverse_video; }; struct grub_arc_component { - unsigned class; - unsigned type; - unsigned flags; - grub_uint16_t version; - grub_uint16_t rev; - grub_uint32_t key; - grub_uint32_t affinity; - grub_uint32_t configdatasize; - grub_uint32_t idlen; + grub_arc_enum_t class; + grub_arc_enum_t type; + grub_arc_enum_t flags; + grub_arc_ushort_t version; + grub_arc_ushort_t rev; + grub_arc_ulong_t key; + grub_arc_ulong_t affinity; + grub_arc_ulong_t configdatasize; + grub_arc_ulong_t idlen; const char *idstr; }; @@ -131,12 +141,12 @@ enum struct grub_arc_fileinfo { - grub_uint64_t start; - grub_uint64_t end; - grub_uint64_t current; - grub_uint32_t type; - grub_uint32_t fnamelength; - grub_uint8_t attr; + grub_arc_ularge_t start; + grub_arc_ularge_t end; + grub_arc_ularge_t current; + grub_arc_enum_t type; + grub_arc_ulong_t fnamelength; + grub_arc_uchar_t attr; char filename[32]; }; @@ -176,54 +186,59 @@ struct grub_arc_firmware_vector struct grub_arc_timeinfo *(*gettime) (void); void *getrelativetime; void *getdirectoryentry; - int (*open) (const char *path, int mode, unsigned *fileno); + grub_arc_err_t (*open) (const char *path, grub_arc_enum_t mode, + grub_arc_fileno_t *fileno); /* 0x60. */ - int (*close) (unsigned fileno); - int (*read) (unsigned fileno, void *buf, unsigned long n, - unsigned long *count); - int (*get_read_status) (unsigned fileno); - int (*write) (unsigned fileno, void *buf, unsigned long n, - unsigned long *count); + grub_arc_err_t (*close) (grub_arc_fileno_t fileno); + grub_arc_err_t (*read) (grub_arc_fileno_t fileno, void *buf, + grub_arc_ulong_t n, + grub_arc_ulong_t *count); + grub_arc_err_t (*get_read_status) (grub_arc_fileno_t fileno); + grub_arc_err_t (*write) (grub_arc_fileno_t fileno, void *buf, + grub_arc_ulong_t n, + grub_arc_ulong_t *count); /* 0x70. */ - int (*seek) (unsigned fileno, grub_uint64_t *pos, int mode); + grub_arc_err_t (*seek) (grub_arc_fileno_t fileno, + grub_arc_ularge_t *pos, grub_arc_enum_t mode); void *mount; void *getenvironmentvariable; void *setenvironmentvariable; /* 0x80. */ - int (*getfileinformation) (unsigned fileno, struct grub_arc_fileinfo *info); + grub_arc_err_t (*getfileinformation) (grub_arc_fileno_t fileno, + struct grub_arc_fileinfo *info); void *setfileinformation; void *flushallcaches; void *testunicodecharacter; /* 0x90. */ - struct grub_arc_display_status * (*getdisplaystatus) (unsigned fileno); + struct grub_arc_display_status * (*getdisplaystatus) (grub_arc_fileno_t fileno); }; struct grub_arc_adapter { - grub_uint32_t adapter_type; - grub_uint32_t adapter_vector_length; + grub_arc_ulong_t adapter_type; + grub_arc_ulong_t adapter_vector_length; void *adapter_vector; }; struct grub_arc_system_parameter_block { - grub_uint32_t signature; - grub_uint32_t length; - grub_uint16_t version; - grub_uint16_t revision; + grub_arc_ulong_t signature; + grub_arc_ulong_t length; + grub_arc_ushort_t version; + grub_arc_ushort_t revision; void *restartblock; void *debugblock; void *gevector; void *utlbmissvector; - grub_uint32_t firmware_vector_length; + grub_arc_ulong_t firmware_vector_length; struct grub_arc_firmware_vector *firmwarevector; - grub_uint32_t private_vector_length; + grub_arc_ulong_t private_vector_length; void *private_vector; - grub_uint32_t adapter_count; + grub_arc_ulong_t adapter_count; struct grub_arc_adapter adapters[0]; }; From 91bbcc0cb666d9f1cc9965e1c692fd0730ab77fd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 20:23:29 +0200 Subject: [PATCH 157/211] * grub-core/boot/mips/yeeloong/fwstart.S: Add explicit set mips3 to avoid asm treating ld and sd as macros. --- ChangeLog | 5 +++++ grub-core/boot/mips/yeeloong/fwstart.S | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index ede161faf..5b73d8884 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-13 Vladimir Serbinenko + + * grub-core/boot/mips/yeeloong/fwstart.S: Add explicit set mips3 + to avoid asm treating ld and sd as macros. + 2011-05-13 Vladimir Serbinenko * grub-core/boot/mips/startup_raw.S: Flush cache after loading diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 9e81df192..2eec876c2 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -28,6 +28,7 @@ .set noreorder .set noat .set nomacro + .set mips3 .global start,_start,__start start: From 19e1c41bbf0638f0504f8cb6faf25c852c49db21 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 20:56:50 +0200 Subject: [PATCH 158/211] Flush caches on DMA memory. * grub-core/kern/mips/cache.S (grub_arch_sync_dma_caches): New function. * grub-core/bus/pci.c (grub_memalign_dma32): Flush caches. (grub_dma_free): Likewise. * include/grub/cache.h (grub_arch_sync_dma_caches): New declaration. --- ChangeLog | 9 +++++++++ grub-core/bus/pci.c | 11 ++++++++++- grub-core/kern/mips/cache.S | 35 +++++++++++++++++++++++++++++++++++ include/grub/cache.h | 10 ++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5b73d8884..49873303c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-05-13 Vladimir Serbinenko + + Flush caches on DMA memory. + + * grub-core/kern/mips/cache.S (grub_arch_sync_dma_caches): New function. + * grub-core/bus/pci.c (grub_memalign_dma32): Flush caches. + (grub_dma_free): Likewise. + * include/grub/cache.h (grub_arch_sync_dma_caches): New declaration. + 2011-05-13 Vladimir Serbinenko * grub-core/boot/mips/yeeloong/fwstart.S: Add explicit set mips3 diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c index 07d20e3f5..766b6d7f1 100644 --- a/grub-core/bus/pci.c +++ b/grub-core/bus/pci.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -28,12 +30,19 @@ GRUB_MOD_LICENSE ("GPLv3+"); struct grub_pci_dma_chunk * grub_memalign_dma32 (grub_size_t align, grub_size_t size) { - return grub_memalign (align, size); + void *ret = grub_memalign (align, size); + if (!ret) + return 0; + grub_arch_sync_dma_caches (ret, size); + return ret; } +/* FIXME: evil. */ void grub_dma_free (struct grub_pci_dma_chunk *ch) { + grub_size_t size = (((struct grub_mm_header *) ch) - 1)->size * GRUB_MM_ALIGN; + grub_arch_sync_dma_caches (ch, size); grub_free (ch); } /* #endif */ diff --git a/grub-core/kern/mips/cache.S b/grub-core/kern/mips/cache.S index 999872f6b..a4aa06fb0 100644 --- a/grub-core/kern/mips/cache.S +++ b/grub-core/kern/mips/cache.S @@ -8,3 +8,38 @@ FUNCTION (grub_cpu_flush_cache) FUNCTION (grub_arch_sync_caches) #include "cache_flush.S" j $ra + +FUNCTION (grub_arch_sync_dma_caches) + move $t2, $a0 + addu $t3, $a0, $a1 + srl $t2, $t2, 5 + sll $t2, $t2, 5 + addu $t3, $t3, 0x1f + srl $t3, $t3, 5 + sll $t3, $t3, 5 + move $t0, $t2 + subu $t1, $t3, $t2 +1: + cache 1, 0($t0) + addiu $t1, $t1, 0xffff + bne $t1, $zero, 1b + addiu $t0, $t0, 0x1 + sync + move $t0, $t2 + subu $t1, $t3, $t2 +2: + cache 0, 0($t0) + addiu $t1, $t1, 0xffff + bne $t1, $zero, 2b + addiu $t0, $t0, 0x1 + sync + move $t0, $t2 + subu $t1, $t3, $t2 +2: + cache 23, 0($t0) + addiu $t1, $t1, 0xffff + bne $t1, $zero, 2b + addiu $t0, $t0, 0x1 + sync + + jr $ra \ No newline at end of file diff --git a/include/grub/cache.h b/include/grub/cache.h index 4f913f5c8..292830566 100644 --- a/include/grub/cache.h +++ b/include/grub/cache.h @@ -37,4 +37,14 @@ grub_arch_sync_caches (void *address __attribute__ ((unused)), void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len); #endif +#ifdef _mips +void EXPORT_FUNC(grub_arch_sync_dma_caches) (void *address, grub_size_t len); +#else +static inline void +grub_arch_sync_dma_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} +#endif + #endif /* ! GRUB_CACHE_HEADER */ From bda0e21993092a324ecee96e5d61c53ef5ebf6a1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 21:31:00 +0200 Subject: [PATCH 159/211] * util/grub-mkimage.c (generate_image): Update hash. --- ChangeLog | 4 ++++ util/grub-mkimage.c | 18 +++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 49873303c..905b0e919 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-05-13 Vladimir Serbinenko + + * util/grub-mkimage.c (generate_image): Update hash. + 2011-05-13 Vladimir Serbinenko Flush caches on DMA memory. diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index b71fb0420..5e964a3e7 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1169,20 +1169,20 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *boot_path, *boot_img; size_t boot_size; grub_uint8_t context[GRUB_MD_SHA512->contextsize]; - /* fwstart.img is the only part which can't be testes by using *-elf + /* fwstart.img is the only part which can't be tested by using *-elf target. Check it against the checksum. This checksum is obtained with sha512sum utility after compiling on Gnewsense. */ const grub_uint8_t fwstart_good_hash[] = { - 0x9f, 0x7f, 0x79, 0x47, 0x68, 0x91, 0x61, 0xb3, - 0x16, 0x7b, 0xf0, 0x27, 0x1c, 0xf7, 0xaf, 0x05, - 0x6c, 0xc1, 0x6f, 0xd2, 0xe7, 0xd1, 0xe9, 0xec, - 0x08, 0x87, 0xe5, 0xc8, 0x29, 0xa2, 0x5b, 0x84, - 0xf8, 0xa6, 0xec, 0x08, 0xf7, 0xcb, 0x7b, 0x6c, - 0xfe, 0x01, 0xfd, 0x5d, 0xba, 0xbf, 0x0d, 0x0f, - 0x2e, 0xef, 0xed, 0x7b, 0xfe, 0xc9, 0x4a, 0x85, - 0xcf, 0xac, 0x20, 0xd7, 0x01, 0xc5, 0xc5, 0x9c + 0x44, 0xce, 0xbc, 0xe7, 0xc2, 0x5e, 0xff, 0x65, + 0xc5, 0xda, 0x29, 0x5a, 0xb9, 0x08, 0x89, 0x42, + 0x83, 0x3f, 0x2b, 0x2e, 0x06, 0xe1, 0x6f, 0x79, + 0x9b, 0x78, 0x6d, 0xe5, 0xd3, 0x64, 0x98, 0x35, + 0xc8, 0x58, 0xac, 0xb8, 0x08, 0x6d, 0x21, 0x51, + 0xcf, 0xe0, 0x76, 0x48, 0x81, 0x6c, 0xed, 0x65, + 0x4a, 0x50, 0xb4, 0x06, 0x38, 0x0b, 0x26, 0x74, + 0x43, 0xbf, 0xc5, 0x2e, 0x07, 0xa6, 0xb8, 0x0e, }; boot_path = grub_util_get_path (dir, "fwstart.img"); From 36084912c0310c7cb42e80b42d0b187bc3775809 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 21:41:18 +0200 Subject: [PATCH 160/211] Give ATA device a bit more time on first try in order to allow disks to spin up. * grub-core/disk/ata.c (grub_atapi_identify): Use GRUB_ATA_TOUT_DEV_INIT if dev->present is 1. Reset dev->present on failure. (grub_ata_device_initialize): Set dev->present to 1. * include/grub/ata.h (GRUB_ATA_TOUT_DEV_INIT): New value. (grub_ata_device): New member 'present'. --- ChangeLog | 11 +++++++++++ grub-core/disk/ata.c | 35 +++++++++++++++++++++++++---------- include/grub/ata.h | 5 ++++- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 905b0e919..e20f2d3cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-05-13 Vladimir Serbinenko + + Give ATA device a bit more time on first try in order to allow disks + to spin up. + + * grub-core/disk/ata.c (grub_atapi_identify): Use GRUB_ATA_TOUT_DEV_INIT + if dev->present is 1. Reset dev->present on failure. + (grub_ata_device_initialize): Set dev->present to 1. + * include/grub/ata.h (GRUB_ATA_TOUT_DEV_INIT): New value. + (grub_ata_device): New member 'present'. + 2011-05-13 Vladimir Serbinenko * util/grub-mkimage.c (generate_image): Update hash. diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 7f261560d..391ccb9a2 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -160,18 +160,23 @@ grub_atapi_identify (struct grub_ata_device *dev) grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4); grub_ata_wait (); - if (grub_ata_check_ready (dev)) + if ((grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY) + && grub_ata_wait_not_busy (dev, dev->present ? GRUB_ATA_TOUT_DEV_INIT + : GRUB_ATA_TOUT_STD)) { grub_free (info); + dev->present = 0; return grub_errno; } grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE); grub_ata_wait (); - if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD)) + if (grub_ata_wait_drq (dev, 0, dev->present ? GRUB_ATA_TOUT_DEV_INIT + : GRUB_ATA_TOUT_STD)) { grub_free (info); + dev->present = 0; return grub_errno; } grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE); @@ -258,8 +263,11 @@ grub_ata_identify (struct grub_ata_device *dev) grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4); grub_ata_wait (); - if (grub_ata_check_ready (dev)) + if ((grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY) + && grub_ata_wait_not_busy (dev, dev->present ? GRUB_ATA_TOUT_DEV_INIT + : GRUB_ATA_TOUT_STD)) { + dev->present = 0; grub_free (info); return grub_errno; } @@ -267,7 +275,8 @@ grub_ata_identify (struct grub_ata_device *dev) grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE); grub_ata_wait (); - if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD)) + if (grub_ata_wait_drq (dev, 0, dev->present ? GRUB_ATA_TOUT_DEV_INIT + : GRUB_ATA_TOUT_STD)) { grub_free (info); grub_errno = GRUB_ERR_NONE; @@ -280,13 +289,18 @@ grub_ata_identify (struct grub_ata_device *dev) return grub_atapi_identify (dev); else if (sts == 0x00) - /* No device, return error but don't print message. */ - return GRUB_ERR_UNKNOWN_DEVICE; - + { + dev->present = 0; + /* No device, return error but don't print message. */ + return GRUB_ERR_UNKNOWN_DEVICE; + } else - /* Other Error. */ - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "device cannot be identified"); + { + dev->present = 0; + /* Other Error. */ + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "device cannot be identified"); + } } grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE); @@ -381,6 +395,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) dev->device = device; dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE; dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE; + dev->present = 1; dev->next = NULL; /* Register the device. */ diff --git a/include/grub/ata.h b/include/grub/ata.h index 9e3aaf0e6..c8f4e5e1b 100644 --- a/include/grub/ata.h +++ b/include/grub/ata.h @@ -94,7 +94,8 @@ enum grub_ata_commands enum grub_ata_timeout_milliseconds { GRUB_ATA_TOUT_STD = 1000, /* 1s standard timeout. */ - GRUB_ATA_TOUT_DATA = 10000 /* 10s DATA I/O timeout. */ + GRUB_ATA_TOUT_DATA = 10000, /* 10s DATA I/O timeout. */ + GRUB_ATA_TOUT_DEV_INIT = 10000, /* Give the device 10s on first try to spinon. */ }; struct grub_ata_device @@ -128,6 +129,8 @@ struct grub_ata_device /* Set to 0 for ATA, set to 1 for ATAPI. */ int atapi; + int present; + struct grub_ata_device *next; }; From 85c6210f6abbb3146d547c33b7e3bd97cdc5751c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 21:50:18 +0200 Subject: [PATCH 161/211] * configure.ac: Bump version to 1.99. --- ChangeLog | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e20f2d3cf..143fc60f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-05-13 Vladimir Serbinenko + + * configure.ac: Bump version to 1.99. + 2011-05-13 Vladimir Serbinenko Give ATA device a bit more time on first try in order to allow disks diff --git a/configure.ac b/configure.ac index 811bd992d..4a05007fd 100644 --- a/configure.ac +++ b/configure.ac @@ -32,7 +32,7 @@ dnl type, so there is no conflict. Variables with the prefix "TARGET_" dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target dnl type. -AC_INIT([GRUB],[1.99~rc2],[bug-grub@gnu.org]) +AC_INIT([GRUB],[1.99],[bug-grub@gnu.org]) AC_CONFIG_AUX_DIR([build-aux]) From 4c2a3b438eadb277a23f9aba650a683cb11d0fb8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 12:09:16 +0200 Subject: [PATCH 162/211] * grub-core/term/at_keyboard.c (set1_e0_mapping): Fix swap between PgUp and PgDown. --- ChangeLog | 5 +++++ grub-core/term/at_keyboard.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 143fc60f5..398495dea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-14 Vladimir Serbinenko + + * grub-core/term/at_keyboard.c (set1_e0_mapping): Fix swap between + PgUp and PgDown. + 2011-05-13 Vladimir Serbinenko * configure.ac: Bump version to 1.99. diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index 56aa7275e..f0f346b1b 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -111,12 +111,12 @@ static const struct {0x38, GRUB_KEYBOARD_KEY_RIGHT_ALT}, {0x47, GRUB_KEYBOARD_KEY_HOME}, {0x48, GRUB_KEYBOARD_KEY_UP}, - {0x49, GRUB_KEYBOARD_KEY_NPAGE}, + {0x49, GRUB_KEYBOARD_KEY_PPAGE}, {0x4b, GRUB_KEYBOARD_KEY_LEFT}, {0x4d, GRUB_KEYBOARD_KEY_RIGHT}, {0x4f, GRUB_KEYBOARD_KEY_END}, {0x50, GRUB_KEYBOARD_KEY_DOWN}, - {0x51, GRUB_KEYBOARD_KEY_PPAGE}, + {0x51, GRUB_KEYBOARD_KEY_NPAGE}, {0x52, GRUB_KEYBOARD_KEY_INSERT}, {0x53, GRUB_KEYBOARD_KEY_DELETE}, }; From d4de6b01e8953039b84205d5ac181cb3615d726e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 12:14:00 +0200 Subject: [PATCH 163/211] * grub-core/commands/menuentry.c (grub_cmd_menuentry): Correctly handle class-free menuentries. (grub_normal_add_menu_entry): Add a check to be sure. --- ChangeLog | 6 ++++++ grub-core/commands/menuentry.c | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 398495dea..466713bfe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-05-14 Vladimir Serbinenko + + * grub-core/commands/menuentry.c (grub_cmd_menuentry): Correctly + handle class-free menuentries. + (grub_normal_add_menu_entry): Add a check to be sure. + 2011-05-14 Vladimir Serbinenko * grub-core/term/at_keyboard.c (set1_e0_mapping): Fix swap between diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index 4dab1783a..4849f8bb8 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -91,7 +91,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, if (! menu_sourcecode) return grub_errno; - if (classes) + if (classes && classes[0]) { int i; for (i = 0; classes[i]; i++); /* count # of menuentry classes */ @@ -255,7 +255,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) if (! ctxt->script) return grub_normal_add_menu_entry (argc, (const char **) args, - ctxt->state[0].args, ctxt->state[1].arg, + (ctxt->state[0].set ? ctxt->state[0].args + : NULL), ctxt->state[1].arg, ctxt->state[2].arg, 0, ctxt->state[3].arg, ctxt->extcmd->cmd->name[0] == 's'); From 2217a1430e285bc78cf595319c128acc8026369d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 17:47:59 +0200 Subject: [PATCH 164/211] Handle module_license on windows. * util/grub-pe2elf.c (MODLICENSE_SECTION): New definition. All following sections shifted. (insert_string): Make argument const char * instead of char *. (write_section_data): Handle long section names. Handle module_license. --- ChangeLog | 10 ++++++++++ util/grub-pe2elf.c | 44 +++++++++++++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 466713bfe..80f21841f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-05-14 Vladimir Serbinenko + + Handle module_license on windows. + + * util/grub-pe2elf.c (MODLICENSE_SECTION): New definition. All following + sections shifted. + (insert_string): Make argument const char * instead of char *. + (write_section_data): Handle long section names. + Handle module_license. + 2011-05-14 Vladimir Serbinenko * grub-core/commands/menuentry.c (grub_cmd_menuentry): Correctly diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c index cf690841f..4b93faa05 100644 --- a/util/grub-pe2elf.c +++ b/util/grub-pe2elf.c @@ -79,11 +79,12 @@ Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); #define BSS_SECTION 4 #define MODNAME_SECTION 5 #define MODDEPS_SECTION 6 -#define SYMTAB_SECTION 7 -#define STRTAB_SECTION 8 +#define MODLICENSE_SECTION 7 +#define SYMTAB_SECTION 8 +#define STRTAB_SECTION 9 -#define REL_SECTION 9 -#define MAX_SECTIONS 12 +#define REL_SECTION 10 +#define MAX_SECTIONS 16 #define STRTAB_BLOCK 256 @@ -96,7 +97,7 @@ int num_sections; grub_uint32_t offset; static int -insert_string (char *name) +insert_string (const char *name) { int len, result; @@ -124,6 +125,8 @@ write_section_data (FILE* fp, char *image, { int *section_map; int i; + char *pe_strtab = (image + pe_chdr->symtab_offset + + pe_chdr->num_symbols * sizeof (struct grub_pe32_symbol)); section_map = xmalloc ((pe_chdr->num_sections + 1) * sizeof (int)); section_map[0] = 0; @@ -131,31 +134,42 @@ write_section_data (FILE* fp, char *image, for (i = 0; i < pe_chdr->num_sections; i++, pe_shdr++) { grub_uint32_t idx; + const char *name = pe_shdr->name; - if (! strcmp (pe_shdr->name, ".text")) + if (name[0] == '/' && isdigit (name[1])) + { + char t[sizeof (pe_shdr->name) + 1]; + memcpy (t, name, sizeof (pe_shdr->name)); + t[sizeof (pe_shdr->name)] = 0; + name = pe_strtab + atoi (t + 1); + } + + if (! strcmp (name, ".text")) { idx = TEXT_SECTION; shdr[idx].sh_flags = SHF_ALLOC | SHF_EXECINSTR; } - else if (! strcmp (pe_shdr->name, ".rdata")) + else if (! strcmp (name, ".rdata")) { idx = RDATA_SECTION; shdr[idx].sh_flags = SHF_ALLOC; } - else if (! strcmp (pe_shdr->name, ".data")) + else if (! strcmp (name, ".data")) { idx = DATA_SECTION; shdr[idx].sh_flags = SHF_ALLOC | SHF_WRITE; } - else if (! strcmp (pe_shdr->name, ".bss")) + else if (! strcmp (name, ".bss")) { idx = BSS_SECTION; shdr[idx].sh_flags = SHF_ALLOC | SHF_WRITE; } - else if (! strcmp (pe_shdr->name, ".modname")) + else if (! strcmp (name, ".modname")) idx = MODNAME_SECTION; - else if (! strcmp (pe_shdr->name, ".moddeps")) + else if (! strcmp (name, ".moddeps")) idx = MODDEPS_SECTION; + else if (strcmp (name, ".module_license") == 0) + idx = MODLICENSE_SECTION; else { section_map[i + 1] = -1; @@ -181,14 +195,14 @@ write_section_data (FILE* fp, char *image, if (pe_shdr->relocations_offset) { - char name[5 + strlen (pe_shdr->name)]; + char relname[5 + strlen (name)]; if (num_sections >= MAX_SECTIONS) grub_util_error ("too many sections"); - sprintf (name, ".rel%s", pe_shdr->name); + sprintf (relname, ".rel%s", name); - shdr[num_sections].sh_name = insert_string (name); + shdr[num_sections].sh_name = insert_string (relname); shdr[num_sections].sh_link = i; shdr[num_sections].sh_info = idx; @@ -197,7 +211,7 @@ write_section_data (FILE* fp, char *image, num_sections++; } else - shdr[idx].sh_name = insert_string (pe_shdr->name); + shdr[idx].sh_name = insert_string (name); } return section_map; From 0cac83df852a8a58d36c0197fb2d3a67fef3488f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 17:50:48 +0200 Subject: [PATCH 165/211] * docs/grub.texi (Installation): Fix several outdated claims. --- ChangeLog | 4 ++++ docs/grub.texi | 62 +++++++++++++------------------------------------- 2 files changed, 20 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 80f21841f..01f216bfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-05-14 Vladimir Serbinenko + + * docs/grub.texi (Installation): Fix several outdated claims. + 2011-05-14 Vladimir Serbinenko Handle module_license on windows. diff --git a/docs/grub.texi b/docs/grub.texi index 95707e4cc..0b7e1098c 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -528,21 +528,15 @@ system (@pxref{Obtaining and Building GRUB}). You can do this either from the source tarball, or as a package for your OS. After you have done that, you need to install the boot loader on a -drive (floppy or hard disk). There are two ways of doing that - either -using the utility @command{grub-install} (@pxref{Invoking -grub-install}) on a UNIX-like OS, or by running GRUB itself from a -floppy. These are quite similar, however the utility might probe a -wrong BIOS drive, so you should be careful. - -Also, if you install GRUB on a UNIX-like OS, please make sure that you -have an emergency boot disk ready, so that you can rescue your computer -if, by any chance, your hard drive becomes unusable (unbootable). +drive (floppy or hard disk) by using the utility +@command{grub-install} (@pxref{Invoking grub-install}) on a UNIX-like OS. GRUB comes with boot images, which are normally put in the directory -@file{/usr/lib/grub/i386-pc}. Hereafter, the directory where GRUB images are -initially placed (normally @file{/usr/lib/grub/i386-pc}) will be +@file{/usr/lib/grub/-} (for BIOS-based machines +@file{/usr/lib/grub/i386-pc}). Hereafter, the directory where GRUB images are +initially placed (normally @file{/usr/lib/grub/-}) will be called the @dfn{image directory}, and the directory where the boot -loader needs to find them (usually @file{/boot/grub}) will be called +loader needs to find them (usually @file{/boot}) will be called the @dfn{boot directory}. @menu @@ -556,27 +550,18 @@ the @dfn{boot directory}. @node Installing GRUB using grub-install @section Installing GRUB using grub-install -@strong{Caution:} This procedure is definitely less safe, because -there are several ways in which your computer can become -unbootable. For example, most operating systems don't tell GRUB how to -map BIOS drives to OS devices correctly---GRUB merely @dfn{guesses} -the mapping. This will succeed in most cases, but not -always. Therefore, GRUB provides you with a map file called the -@dfn{device map}, which you must fix if it is wrong. @xref{Device -map}, for more details. - For information on where GRUB should be installed on PC BIOS platforms, @pxref{BIOS installation}. -If you still do want to install GRUB under a UNIX-like OS (such +In order to install GRUB under a UNIX-like OS (such as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking grub-install}) as the superuser (@dfn{root}). The usage is basically very simple. You only need to specify one argument to the program, namely, where to install the boot loader. The -argument can be either a device file (like @samp{/dev/hda}) or a -partition specified in GRUB's notation. For example, under Linux the -following will install GRUB into the MBR of the first IDE disk: +argument has to be either a device file (like @samp{/dev/hda}). +For example, under Linux the following will install GRUB into the MBR +of the first IDE disk: @example # @kbd{grub-install /dev/hda} @@ -588,37 +573,22 @@ Likewise, under GNU/Hurd, this has the same effect: # @kbd{grub-install /dev/hd0} @end example -But all the above examples assume that GRUB should use images under -the root directory. If you want GRUB to use images under a directory -other than the root directory, you need to specify the option -@option{--root-directory}. The typical usage is that you create a GRUB +But all the above examples assume that GRUB should put images under +the @file{/boot} directory. If you want GRUB to put images under a directory +other than @file{/boot}, you need to specify the option +@option{--boot-directory}. The typical usage is that you create a GRUB boot floppy with a filesystem. Here is an example: @example @group # @kbd{mke2fs /dev/fd0} # @kbd{mount -t ext2 /dev/fd0 /mnt} -# @kbd{grub-install --root-directory=/mnt fd0} +# @kbd{mkdir /mnt/boot} +# @kbd{grub-install --boot-directory=/mnt/boot /dev/fd0} # @kbd{umount /mnt} @end group @end example -Another example is when you have a separate boot partition -which is mounted at @file{/boot}. Since GRUB is a boot loader, it -doesn't know anything about mountpoints at all. Thus, you need to run -@command{grub-install} like this: - -@example -# @kbd{grub-install --root-directory=/boot /dev/hda} -@end example - -By the way, as noted above, it is quite difficult to guess BIOS drives -correctly under a UNIX-like OS. Thus, @command{grub-install} will prompt -you to check if it could really guess the correct mappings, after the -installation. The format is defined in @ref{Device map}. Please be -quite careful. If the output is wrong, it is unlikely that your -computer will be able to boot with no problem. - Some BIOSes have a bug of exposing the first partition of a USB drive as a floppy instead of exposing the USB drive as a hard disk (they call it ``USB-FDD'' boot). In such cases, you need to install like this: From 25a45338751d8ed2f8bed7231380a4e8183e585c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 22:26:52 +0200 Subject: [PATCH 166/211] Fix few potential memory misusage. * grub-core/font/font.c (load_font_index): Don't free char_index to avoid double free. --- ChangeLog | 7 +++++++ grub-core/font/font.c | 13 ++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 01f216bfb..f316af0b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-05-14 Vladimir Serbinenko + + Fix few potential memory misusage. + + * grub-core/font/font.c (load_font_index): Don't free char_index to + avoid double free. + 2011-05-14 Vladimir Serbinenko * docs/grub.texi (Installation): Fix several outdated claims. diff --git a/grub-core/font/font.c b/grub-core/font/font.c index ef6caf77b..26eac4c05 100644 --- a/grub-core/font/font.c +++ b/grub-core/font/font.c @@ -316,10 +316,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct return 1; font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); if (!font->bmp_idx) - { - grub_free (font->char_index); - return 1; - } + return 1; grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t)); @@ -494,7 +491,7 @@ grub_font_load (const char *filename) #endif /* Allocate the font object. */ - font = (grub_font_t) grub_malloc (sizeof (struct grub_font)); + font = (grub_font_t) grub_zalloc (sizeof (struct grub_font)); if (!font) goto fail; @@ -640,6 +637,11 @@ grub_font_load (const char *filename) return 0; fail: + if (file) + grub_file_close (file); + if (font) + font->file = 0; + free_font (font); return 1; } @@ -799,6 +801,7 @@ free_font (grub_font_t font) grub_free (font->name); grub_free (font->family); grub_free (font->char_index); + grub_free (font->bmp_idx); grub_free (font); } } From b25db2188538c628f79ded0a3e17f77ccb8ebfa3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 22:29:27 +0200 Subject: [PATCH 167/211] * grub-core/font/font_cmd.c (loadfont_command): Set grub_errno on error if not already done. --- ChangeLog | 8 ++++++++ grub-core/font/font_cmd.c | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f316af0b1..bb4d0aade 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,17 @@ +2011-05-14 Vladimir Serbinenko + + * grub-core/font/font_cmd.c (loadfont_command): Set grub_errno + on error if not already done. + 2011-05-14 Vladimir Serbinenko Fix few potential memory misusage. * grub-core/font/font.c (load_font_index): Don't free char_index to avoid double free. + (grub_font_load): Zero-fill font at alloc for safety. + Close file on error. + (free_font): Free bmp_idx. 2011-05-14 Vladimir Serbinenko diff --git a/grub-core/font/font_cmd.c b/grub-core/font/font_cmd.c index 8b00dd8b9..98f0b88d6 100644 --- a/grub-core/font/font_cmd.c +++ b/grub-core/font/font_cmd.c @@ -33,7 +33,11 @@ loadfont_command (grub_command_t cmd __attribute__ ((unused)), while (argc--) if (grub_font_load (*args++) != 0) - return GRUB_ERR_BAD_FONT; + { + if (!grub_errno) + return grub_error (GRUB_ERR_BAD_FONT, "invalid font"); + return grub_errno; + } return GRUB_ERR_NONE; } From 3d2c7e3591e3f0d4949e5822bfafb67f2b0dc476 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 22:35:56 +0200 Subject: [PATCH 168/211] * grub-core/kern/dl.c (grub_dl_unload): Don't decrease reference counter on dependencies since grub_dl_unref already handles this. --- ChangeLog | 5 +++++ grub-core/kern/dl.c | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb4d0aade..6777eb0f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-14 Vladimir Serbinenko + + * grub-core/kern/dl.c (grub_dl_unload): Don't decrease reference + counter on dependencies since grub_dl_unref already handles this. + 2011-05-14 Vladimir Serbinenko * grub-core/font/font_cmd.c (loadfont_command): Set grub_errno diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index c5e2888cd..6104f229e 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -683,8 +683,7 @@ grub_dl_unload (grub_dl_t mod) { depn = dep->next; - if (! grub_dl_unref (dep->mod)) - grub_dl_unload (dep->mod); + grub_dl_unload (dep->mod); grub_free (dep); } From 576881217f04b6938f3dd8e15ce93ad6fa3170cd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 22:42:28 +0200 Subject: [PATCH 169/211] * grub-core/kern/dl.c (grub_dl_load_file): Decrease ref counter rather than resetting it to allow modules to reference themselves in init. --- ChangeLog | 6 ++++++ grub-core/kern/dl.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6777eb0f4..429467d02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-05-14 Vladimir Serbinenko + + * grub-core/kern/dl.c (grub_dl_load_file): Decrease ref counter + rather than resetting it to allow modules to reference themselves + in init. + 2011-05-14 Vladimir Serbinenko * grub-core/kern/dl.c (grub_dl_unload): Don't decrease reference diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 6104f229e..623e0cbcb 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -626,7 +626,7 @@ grub_dl_load_file (const char *filename) return 0; } - mod->ref_count = 0; + mod->ref_count--; return mod; } From de04eecfa9df533f69f59a4be23e1ebbe8fe898a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 22:44:53 +0200 Subject: [PATCH 170/211] * grub-core/kern/mm.c (grub_memalign): Disable auto-unloadding of unused modules since currently referrence counter isn't reliable and there isn't much memory to recover there anyway. --- ChangeLog | 6 ++++++ grub-core/kern/mm.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 429467d02..a0efb24e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-05-14 Vladimir Serbinenko + + * grub-core/kern/mm.c (grub_memalign): Disable auto-unloadding of + unused modules since currently referrence counter isn't reliable and + there isn't much memory to recover there anyway. + 2011-05-14 Vladimir Serbinenko * grub-core/kern/dl.c (grub_dl_load_file): Decrease ref counter diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c index 8d9b5db78..d54f3f240 100644 --- a/grub-core/kern/mm.c +++ b/grub-core/kern/mm.c @@ -311,11 +311,13 @@ grub_memalign (grub_size_t align, grub_size_t size) count++; goto again; +#if 0 case 1: /* Unload unneeded modules. */ grub_dl_unload_unneeded (); count++; goto again; +#endif default: break; From 90c571a47fb9a100938707fdeba81e6d6fea4c33 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 May 2011 22:47:28 +0200 Subject: [PATCH 171/211] * util/grub.d/10_linux.in: Autoload gzio since it's needed on some platforms if kernel is compressed. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index a0efb24e8..68a13a72e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-14 Vladimir Serbinenko + + * util/grub.d/10_linux.in: Autoload gzio since it's needed on some + platforms if kernel is compressed. + 2011-05-14 Vladimir Serbinenko * grub-core/kern/mm.c (grub_memalign): Disable auto-unloadding of diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 3c3a2a5d5..1d1eb403f 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -98,6 +98,10 @@ EOF EOF fi + cat << EOF + insmod gzio +EOF + if [ x$dirname = x/ ]; then if [ -z "${prepare_root_cache}" ]; then prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/")" From 6ada82d14df6c66cbb433d383e5f2d86e865d7c2 Mon Sep 17 00:00:00 2001 From: Jordan Uggla Date: Sat, 14 May 2011 22:49:53 +0200 Subject: [PATCH 172/211] * docs/grub.texi (Invoking grub-install): Fix additional outdated claims and add some clarification. --- ChangeLog | 5 +++++ docs/grub.texi | 27 ++++++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68a13a72e..9575204c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-14 Jordan Uggla + + * docs/grub.texi (Invoking grub-install): Fix additional outdated claims + and add some clarification. + 2011-05-14 Vladimir Serbinenko * util/grub.d/10_linux.in: Autoload gzio since it's needed on some diff --git a/docs/grub.texi b/docs/grub.texi index 0b7e1098c..b11e3836f 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -4165,15 +4165,28 @@ Print a summary of the command-line options and exit. @item --version Print the version number of GRUB and exit. -@item --root-directory=@var{dir} -Install GRUB images under the directory @var{dir} instead of the root -directory. This option is useful when you want to install GRUB into a -separate partition or a removable disk. Here is an example in which -you have a separate @dfn{boot} partition which is mounted on -@file{/boot}: +@item --boot-directory=@var{dir} +Install GRUB images under the directory @file{@var{dir}/grub/} +This option is useful when you want to install GRUB into a +separate partition or a removable disk. +If this option is not specified then it defaults to @file{/boot}, so @example -@kbd{grub-install --root-directory=/boot hd0} +@kbd{grub-install /dev/sda} +@end example + +is equivalent to + +@example +@kbd{grub-install --boot-directory=/boot/ /dev/sda} +@end example + +Here is an example in which you have a separate @dfn{boot} partition which is +mounted on +@file{/mnt/boot}: + +@example +@kbd{grub-install --boot-directory=/mnt/boot /dev/sdb} @end example @item --recheck From 983b414d776f638e9cb80988fcce7255cf162dd2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 15 May 2011 10:23:02 +0200 Subject: [PATCH 173/211] * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Silence spurious warning. Move variables before code while on it. --- ChangeLog | 5 +++++ grub-core/fs/btrfs.c | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 505be20c2..ab247969e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-15 Vladimir Serbinenko + + * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Silence spurious + warning. Move variables before code while on it. + 2011-05-15 Vladimir Serbinenko Fuloong support. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 42aa257d9..59e91b552 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -589,10 +589,14 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, struct grub_btrfs_key *key; struct grub_btrfs_chunk_item *chunk; grub_uint64_t csize; - grub_err_t err; + grub_err_t err = 0; struct grub_btrfs_key key_out; int challoc = 0; grub_device_t dev; + struct grub_btrfs_key key_in; + grub_size_t chsize; + grub_disk_addr_t chaddr; + grub_dprintf ("btrfs", "searching for laddr %" PRIxGRUB_UINT64_T "\n", addr); for (ptr = data->sblock.bootstrap_mapping; @@ -616,9 +620,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, + sizeof (struct grub_btrfs_chunk_stripe) * grub_le_to_cpu16 (chunk->nstripes); } - struct grub_btrfs_key key_in; - grub_size_t chsize; - grub_disk_addr_t chaddr; + key_in.object_id = GRUB_BTRFS_OBJECT_ID_CHUNK; key_in.type = GRUB_BTRFS_ITEM_TYPE_CHUNK; key_in.offset = addr; From 67b1e5c9079ae6fb734e69aa07a78e6a52d5eb56 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 15 May 2011 12:32:37 +0200 Subject: [PATCH 174/211] Fix compilation errors. * grub-core/term/ns8250.c (serial_get_divisor): Declare 'port' as potentially unused. * grub-core/loader/i386/linux.c (grub_linux_setup_video): Handle GRUB_VIDEO_DRIVER_SIS315PRO. * grub-core/bus/cs5536.c (grub_cs5536_init_geode): Restrict DIVIL init to loongson machines. --- ChangeLog | 11 +++++++++++ grub-core/bus/cs5536.c | 2 ++ grub-core/loader/i386/linux.c | 1 + grub-core/term/ns8250.c | 2 +- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a2927df11..98418f4a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-05-15 Vladimir Serbinenko + + Fix compilation errors. + + * grub-core/term/ns8250.c (serial_get_divisor): Declare 'port' as + potentially unused. + * grub-core/loader/i386/linux.c (grub_linux_setup_video): + Handle GRUB_VIDEO_DRIVER_SIS315PRO. + * grub-core/bus/cs5536.c (grub_cs5536_init_geode): Restrict DIVIL init + to loongson machines. + 2011-05-15 Vladimir Serbinenko Several FS mtime support. diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c index f1a564251..ae3c5c878 100644 --- a/grub-core/bus/cs5536.c +++ b/grub-core/bus/cs5536.c @@ -269,6 +269,7 @@ grub_cs5536_init_geode (grub_pci_device_t dev) GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM); /* Setup DIVIL. */ +#ifdef GRUB_MACHINE_MIPS_LOONGSON switch (grub_arch_machine) { case GRUB_ARCH_MACHINE_YEELOONG: @@ -288,6 +289,7 @@ grub_cs5536_init_geode (grub_pci_device_t dev) | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); break; } +#endif grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK, (~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff); grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK, diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index f19f471ab..dc2af4093 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -367,6 +367,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) /* FIXME: check if better id is available. */ case GRUB_VIDEO_DRIVER_SM712: + case GRUB_VIDEO_DRIVER_SIS315PRO: case GRUB_VIDEO_DRIVER_VGA: case GRUB_VIDEO_DRIVER_CIRRUS: case GRUB_VIDEO_DRIVER_BOCHS: diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c index b63ee14d9..996fc81f3 100644 --- a/grub-core/term/ns8250.c +++ b/grub-core/term/ns8250.c @@ -37,7 +37,7 @@ static const grub_port_t serial_hw_io_addr[] = GRUB_MACHINE_SERIAL_PORTS; /* Convert speed to divisor. */ static unsigned short -serial_get_divisor (const struct grub_serial_port *port, +serial_get_divisor (const struct grub_serial_port *port __attribute__ ((unused)), const struct grub_serial_config *config) { unsigned int i; From c3fc520c0d5b05cc3f75b20a42f51f8fd5ca8519 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 15 May 2011 15:41:23 +0200 Subject: [PATCH 175/211] * grub-core/bus/cs5536.c: Don't include grub/machine/kernel.h on non-loongson. * grub-core/kern/mips/dl.c (grub_arch_dl_init_linker): Fix argument to grub_dl_register_symbol. --- ChangeLog | 7 +++++++ grub-core/bus/cs5536.c | 2 ++ grub-core/kern/mips/dl.c | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 98418f4a0..cdf602203 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-05-15 Vladimir Serbinenko + + * grub-core/bus/cs5536.c: Don't include grub/machine/kernel.h on + non-loongson. + * grub-core/kern/mips/dl.c (grub_arch_dl_init_linker): Fix argument + to grub_dl_register_symbol. + 2011-05-15 Vladimir Serbinenko Fix compilation errors. diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c index ae3c5c878..58ffeb60a 100644 --- a/grub-core/bus/cs5536.c +++ b/grub-core/bus/cs5536.c @@ -21,7 +21,9 @@ #include #include #include +#ifdef GRUB_MACHINE_MIPS_LOONGSON #include +#endif #include diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c index e17e9f30b..2ddbed3e6 100644 --- a/grub-core/kern/mips/dl.c +++ b/grub-core/kern/mips/dl.c @@ -234,6 +234,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) void grub_arch_dl_init_linker (void) { - grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0); + grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0, 0); } From 736e0ade54b07ab10e8d98b54ecb6c43e779b04d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 16 May 2011 02:34:58 +0200 Subject: [PATCH 176/211] Fuloong video init support. * include/grub/vga.h (grub_vga_write_arx): inb monochrome address as well. (grub_vga_read_arx): New function. * grub-core/video/sis315pro.c (GRUB_SIS315PRO_MMIO_SPACE): New definition. (framebuffer): New members io, mmioptr and mmiobase. (read_sis_cmd): New function. (write_sis_cmd): Likewise. (grub_video_sis315pro_setup): Do the initialisation. Use 640x480 rather than 640x400. * grub-core/video/sis315_init.c: New file. --- grub-core/video/sis315_init.c | 158 ++++++++++++++++++++++++++ grub-core/video/sis315pro.c | 208 +++++++++++++++++++++++++++++++++- include/grub/vga.h | 15 ++- 3 files changed, 377 insertions(+), 4 deletions(-) create mode 100644 grub-core/video/sis315_init.c diff --git a/grub-core/video/sis315_init.c b/grub-core/video/sis315_init.c new file mode 100644 index 000000000..ae5c1419c --- /dev/null +++ b/grub-core/video/sis315_init.c @@ -0,0 +1,158 @@ +static const struct { grub_uint8_t reg; grub_uint8_t val; } sr_dump [] = +{ + { 0x28, 0x81 }, + { 0x2a, 0x00 }, + { 0x29, 0xe1 }, + { 0x2b, 0x81 }, + { 0x2d, 0x00 }, + { 0x2c, 0xe1 }, + { 0x2e, 0x81 }, + { 0x30, 0x00 }, + { 0x2f, 0xe1 }, + { 0x28, 0x01 }, + { 0x29, 0x22 }, + { 0x28, 0x3b }, + { 0x29, 0x22 }, + { 0x2a, 0x01 }, + { 0x2e, 0x01 }, + { 0x2f, 0x22 }, + { 0x2e, 0x3b }, + { 0x2f, 0x22 }, + { 0x30, 0x01 }, + { 0x15, 0x00 }, + { 0x1b, 0x30 }, + + { 0x16, 0x0f }, + { 0x16, 0x8f }, + { 0x17, 0xba }, + { 0x16, 0x0f }, + { 0x16, 0x8f }, + { 0x1f, 0x00 }, + { 0x20, 0x20 }, + { 0x23, 0xf6 }, + { 0x24, 0x0d }, + { 0x25, 0x33 }, + { 0x21, 0x84 }, + { 0x22, 0x00 }, + { 0x27, 0x1f }, + { 0x31, 0x00 }, + { 0x33, 0x00 }, + { 0x32, 0x11 }, + + { 0x25, 0x33 }, + + { 0x05, 0x86 }, + { 0x01, 0x20 }, + { 0x32, 0x11 }, + { 0x1e, 0x00 }, + { 0x1d, 0x00 }, + { 0x00, 0x03 }, + { 0x01, 0x21 }, + { 0x02, 0x0f }, + { 0x03, 0x00 }, + { 0x04, 0x0e }, + + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x0c, 0x00 }, + { 0x0d, 0x00 }, + { 0x0e, 0x00 }, + { 0x37, 0x00 }, + + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x0c, 0x05 }, + { 0x0e, 0x00 }, + + { 0x0e, 0x00 }, + + { 0x10, 0x0b }, + { 0x31, 0x00 }, + { 0x2b, 0x01 }, + { 0x2c, 0xe1 }, + { 0x2b, 0x1b }, + { 0x2c, 0xe1 }, + { 0x2d, 0x01 }, + { 0x3d, 0x00 }, + { 0x08, 0x84 }, + { 0x09, 0x00 }, + { 0x3d, 0x01 }, + { 0x1f, 0x00 }, + { 0x06, 0x02 }, + + { 0x0f, 0x00 }, + { 0x17, 0xba }, + { 0x21, 0xa4 }, + { 0x32, 0x11 }, + { 0x07, 0x18 }, + + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + + { 0x01, 0x01 }, + { 0x21, 0x84 }, + { 0x01, 0x21 }, + { 0x16, 0x8f }, + { 0x18, 0xa9 }, + { 0x19, 0xa0 }, + { 0x1b, 0x30 }, + { 0x17, 0xb8 }, + { 0x19, 0xa3 }, + { 0x13, 0x00 }, + { 0x14, 0x00 }, + { 0x14, 0x02 }, + { 0x15, 0x00 }, + { 0x16, 0x0f }, + { 0x16, 0x8f }, + { 0x1d, 0x00 }, + { 0x14, 0x00 }, + { 0x14, 0x01 }, + { 0x15, 0x00 }, + { 0x16, 0x0f }, + { 0x16, 0x8f }, + { 0x1d, 0x00 }, + { 0x14, 0x01 }, + { 0x14, 0x01 }, + { 0x15, 0x10 }, + { 0x13, 0x35 }, + { 0x14, 0x51 }, + { 0x16, 0x0f }, + { 0x16, 0x8f }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x11 }, + { 0x1d, 0x11 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x1d, 0x00 }, + { 0x17, 0xba }, + { 0x19, 0xa0 }, + { 0x19, 0xa0 }, + { 0x01, 0x01 }, + { 0x16, 0x0f }, + { 0x18, 0xa9 }, + { 0x19, 0xa0 }, + { 0x1b, 0x30 }, + { 0x21, 0xa4 }, + { 0x05, 0x86 }, +}; + +static const grub_uint8_t gr[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c index 59ff6432d..22064c91e 100644 --- a/grub-core/video/sis315pro.c +++ b/grub-core/video/sis315pro.c @@ -30,6 +30,7 @@ #define GRUB_SIS315PRO_PCIID 0x03251039 #define GRUB_SIS315PRO_TOTAL_MEMORY_SPACE 0x800000 +#define GRUB_SIS315PRO_MMIO_SPACE 0x1000 static struct { @@ -39,9 +40,26 @@ static struct grub_uint8_t *ptr; int mapped; grub_uint32_t base; + grub_uint32_t mmiobase; + volatile grub_uint32_t *mmioptr; grub_pci_device_t dev; + grub_port_t io; } framebuffer; +static grub_uint8_t +read_sis_cmd (grub_uint8_t addr) +{ + grub_outb (addr, framebuffer.io + 0x44); + return grub_inb (framebuffer.io + 0x45); +} + +static void +write_sis_cmd (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, framebuffer.io + 0x44); + grub_outb (val, framebuffer.io + 0x45); +} + #ifndef TEST static grub_err_t grub_video_sis315pro_video_init (void) @@ -63,6 +81,8 @@ grub_video_sis315pro_video_fini (void) } #endif +#include "sis315_init.c" + static grub_err_t grub_video_sis315pro_setup (unsigned int width, unsigned int height, unsigned int mode_type, @@ -71,6 +91,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, int depth; grub_err_t err; int found = 0; + unsigned i; #ifndef TEST auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); @@ -89,7 +110,12 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, found = 1; addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - framebuffer.base = grub_pci_read (addr); + framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); + framebuffer.mmiobase = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG2); + framebuffer.io = (grub_pci_read (addr) & GRUB_PCI_ADDR_IO_MASK) + + GRUB_MACHINE_PCI_IO_BASE; framebuffer.dev = dev; return 1; @@ -99,7 +125,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; - if ((width != 640 && width != 0) || (height != 400 && height != 0) + if ((width != 640 && width != 0) || (height != 480 && height != 0) || (depth != 8 && depth != 0)) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Only 640x400x8 is supported"); @@ -110,7 +136,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, #endif /* Fill mode info details. */ framebuffer.mode_info.width = 640; - framebuffer.mode_info.height = 400; + framebuffer.mode_info.height = 480; framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; framebuffer.mode_info.bpp = 8; framebuffer.mode_info.bytes_per_pixel = 1; @@ -129,12 +155,49 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, = grub_video_get_blit_format (&framebuffer.mode_info); #endif +#ifndef TEST + if (found && (framebuffer.base == 0 || framebuffer.mmiobase == 0)) + { + grub_pci_address_t addr; + /* FIXME: choose address dynamically if needed. */ + framebuffer.base = 0x40000000; + framebuffer.mmiobase = 0x04000000; + framebuffer.io = 0xb300; + + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, framebuffer.base | GRUB_PCI_ADDR_MEM_PREFETCH); + + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG1); + grub_pci_write (addr, framebuffer.mmiobase); + + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG2); + grub_pci_write (addr, framebuffer.io | GRUB_PCI_ADDR_SPACE_IO); + + /* Set latency. */ + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_CACHELINE); + grub_pci_write (addr, 0x80004700); + + /* Enable address spaces. */ + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND); + grub_pci_write (addr, 0x7); + + addr = grub_pci_make_address (framebuffer.dev, 0x30); + grub_pci_write (addr, 0x04060001); + + framebuffer.io += GRUB_MACHINE_PCI_IO_BASE; + } +#endif + + /* We can safely discard volatile attribute. */ #ifndef TEST framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev, framebuffer.base, GRUB_SIS315PRO_TOTAL_MEMORY_SPACE); + framebuffer.mmioptr = grub_pci_device_map_range (framebuffer.dev, + framebuffer.mmiobase, + GRUB_SIS315PRO_MMIO_SPACE); #endif framebuffer.mapped = 1; @@ -144,6 +207,145 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, framebuffer.mode_info.height * framebuffer.mode_info.pitch); #endif + grub_outb (GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY + | GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY + | GRUB_VGA_IO_MISC_UPPER_64K + | GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 + | GRUB_VGA_IO_MISC_28MHZ + | GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS + | GRUB_VGA_IO_MISC_COLOR, + GRUB_VGA_IO_MISC_WRITE + GRUB_MACHINE_PCI_IO_BASE); + + grub_vga_sr_write (0x86, 5); + for (i = 6; i <= 0x27; i++) + grub_vga_sr_write (0, i); + + for (i = 0x31; i <= 0x3d; i++) + grub_vga_sr_write (0, i); + + for (i = 0; i < ARRAY_SIZE (sr_dump); i++) + grub_vga_sr_write (sr_dump[i].val, sr_dump[i].reg); + + for (i = 0x30; i < 0x40; i++) + grub_vga_cr_write (0, i); + + grub_vga_cr_write (0x77, 0x40); + grub_vga_cr_write (0x77, 0x41); + grub_vga_cr_write (0x00, 0x42); + grub_vga_cr_write (0x5b, 0x43); + grub_vga_cr_write (0x00, 0x44); + grub_vga_cr_write (0x23, 0x48); + grub_vga_cr_write (0xaa, 0x49); + grub_vga_cr_write (0x02, 0x37); + grub_vga_cr_write (0x20, 0x5b); + grub_vga_cr_write (0x00, 0x83); + grub_vga_cr_write (0x80, 0x63); + + grub_vga_cr_write (0x0c, GRUB_VGA_CR_VSYNC_END); + grub_vga_cr_write (0x5f, GRUB_VGA_CR_HTOTAL); + grub_vga_cr_write (0x4f, GRUB_VGA_CR_HORIZ_END); + grub_vga_cr_write (0x50, GRUB_VGA_CR_HBLANK_START); + grub_vga_cr_write (0x82, GRUB_VGA_CR_HBLANK_END); + grub_vga_cr_write (0x54, GRUB_VGA_CR_HORIZ_SYNC_PULSE_START); + grub_vga_cr_write (0x80, GRUB_VGA_CR_HORIZ_SYNC_PULSE_END); + grub_vga_cr_write (0x0b, GRUB_VGA_CR_VERT_TOTAL); + grub_vga_cr_write (0x3e, GRUB_VGA_CR_OVERFLOW); + grub_vga_cr_write (0x00, GRUB_VGA_CR_BYTE_PANNING); + grub_vga_cr_write (0x40, GRUB_VGA_CR_CELL_HEIGHT); + grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_START); + grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_END); + grub_vga_cr_write (0x00, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); + grub_vga_cr_write (0x00, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); + grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_ADDR_HIGH); + grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_ADDR_LOW); + grub_vga_cr_write (0xea, GRUB_VGA_CR_VSYNC_START); + grub_vga_cr_write (0x8c, GRUB_VGA_CR_VSYNC_END); + grub_vga_cr_write (0xdf, GRUB_VGA_CR_VDISPLAY_END); + grub_vga_cr_write (0x28, GRUB_VGA_CR_PITCH); + grub_vga_cr_write (0x40, GRUB_VGA_CR_UNDERLINE_LOCATION); + grub_vga_cr_write (0xe7, GRUB_VGA_CR_VERTICAL_BLANK_START); + grub_vga_cr_write (0x04, GRUB_VGA_CR_VERTICAL_BLANK_END); + grub_vga_cr_write (0xa3, GRUB_VGA_CR_MODE); + grub_vga_cr_write (0xff, GRUB_VGA_CR_LINE_COMPARE); + + grub_vga_cr_write (0x0c, GRUB_VGA_CR_VSYNC_END); + grub_vga_cr_write (0x5f, GRUB_VGA_CR_HTOTAL); + grub_vga_cr_write (0x4f, GRUB_VGA_CR_HORIZ_END); + grub_vga_cr_write (0x50, GRUB_VGA_CR_HBLANK_START); + grub_vga_cr_write (0x82, GRUB_VGA_CR_HBLANK_END); + grub_vga_cr_write (0x55, GRUB_VGA_CR_HORIZ_SYNC_PULSE_START); + grub_vga_cr_write (0x81, GRUB_VGA_CR_HORIZ_SYNC_PULSE_END); + grub_vga_cr_write (0x0b, GRUB_VGA_CR_VERT_TOTAL); + grub_vga_cr_write (0x3e, GRUB_VGA_CR_OVERFLOW); + grub_vga_cr_write (0xe9, GRUB_VGA_CR_VSYNC_START); + grub_vga_cr_write (0x8b, GRUB_VGA_CR_VSYNC_END); + grub_vga_cr_write (0xdf, GRUB_VGA_CR_VDISPLAY_END); + grub_vga_cr_write (0xe7, GRUB_VGA_CR_VERTICAL_BLANK_START); + grub_vga_cr_write (0x04, GRUB_VGA_CR_VERTICAL_BLANK_END); + grub_vga_cr_write (0x40, GRUB_VGA_CR_CELL_HEIGHT); + grub_vga_cr_write (0x50, GRUB_VGA_CR_PITCH); + + grub_vga_cr_write (0x00, 0x19); + grub_vga_cr_write (0x00, 0x1a); + grub_vga_cr_write (0x6c, 0x52); + grub_vga_cr_write (0x2e, 0x34); + grub_vga_cr_write (0x00, 0x31); + + + grub_vga_cr_write (0, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); + grub_vga_cr_write (0, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); + + for (i = 0; i < 16; i++) + grub_vga_write_arx (i, i); + grub_vga_write_arx (1, GRUB_VGA_ARX_MODE); + grub_vga_write_arx (0, GRUB_VGA_ARX_OVERSCAN); + grub_vga_write_arx (0, GRUB_VGA_ARX_COLOR_PLANE_ENABLE); + grub_vga_write_arx (0, GRUB_VGA_ARX_HORIZONTAL_PANNING); + grub_vga_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT); + + grub_outb (0xff, GRUB_VGA_IO_PIXEL_MASK + GRUB_MACHINE_PCI_IO_BASE); + + for (i = 0; i < ARRAY_SIZE (gr); i++) + grub_vga_gr_write (gr[i], i); + + for (i = 0; i < GRUB_VIDEO_FBSTD_NUMCOLORS; i++) + grub_vga_palette_write (i, grub_video_fbstd_colors[i].r, + grub_video_fbstd_colors[i].g, + grub_video_fbstd_colors[i].b); + +#if 1 + { + if (read_sis_cmd (0x5) != 0xa1) + write_sis_cmd (0x86, 0x5); + + write_sis_cmd (read_sis_cmd (0x20) | 0xa1, 0x20); + write_sis_cmd (read_sis_cmd (0x1e) | 0xda, 0x1e); + +#define IND_SIS_CMDQUEUE_SET 0x26 +#define IND_SIS_CMDQUEUE_THRESHOLD 0x27 + +#define COMMAND_QUEUE_THRESHOLD 0x1F +#define SIS_CMD_QUEUE_RESET 0x01 + +#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330/340 series SR26 */ +#define SIS_VRAM_CMDQUEUE_ENABLE 0x40 +#define SIS_MMIO_CMD_ENABLE 0x20 +#define SIS_CMD_QUEUE_SIZE_512k 0x00 +#define SIS_CMD_QUEUE_SIZE_1M 0x04 +#define SIS_CMD_QUEUE_SIZE_2M 0x08 +#define SIS_CMD_QUEUE_SIZE_4M 0x0C +#define SIS_CMD_QUEUE_RESET 0x01 +#define SIS_CMD_AUTO_CORR 0x02 + + + write_sis_cmd (COMMAND_QUEUE_THRESHOLD, IND_SIS_CMDQUEUE_THRESHOLD); + write_sis_cmd (SIS_CMD_QUEUE_RESET, IND_SIS_CMDQUEUE_SET); + framebuffer.mmioptr[0x85C4 / 4] = framebuffer.mmioptr[0x85C8 / 4]; + write_sis_cmd (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR, IND_SIS_CMDQUEUE_SET); + framebuffer.mmioptr[0x85C0 / 4] = (0x1000000 - (512 * 1024)); + } +#endif + #ifndef TEST err = grub_video_fb_create_render_target_from_pointer (&framebuffer .render_target, diff --git a/include/grub/vga.h b/include/grub/vga.h index 7f112d83a..bf4439599 100644 --- a/include/grub/vga.h +++ b/include/grub/vga.h @@ -84,8 +84,8 @@ enum { GRUB_VGA_IO_MISC_COLOR = 0x01, GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS = 0x02, - GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 = 0x08, GRUB_VGA_IO_MISC_28MHZ = 0x04, + GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 = 0x08, GRUB_VGA_IO_MISC_UPPER_64K = 0x20, GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY = 0x40, GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY = 0x80, @@ -290,11 +290,24 @@ static inline void grub_vga_write_arx (grub_uint8_t val, grub_uint8_t addr) { grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_INPUT_STATUS1_REGISTER); + grub_inb (GRUB_MACHINE_PCI_IO_BASE + 0x3ba); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX_READ); grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); } +static inline grub_uint8_t +grub_vga_read_arx (grub_uint8_t addr) +{ + grub_uint8_t val; + grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_INPUT_STATUS1_REGISTER); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); + val = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX_READ); + grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); + return val; +} + struct grub_video_hw_config { unsigned vertical_total; From 638dbe4f27f481d57de39f2847e4c2b8992dbfcf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 16 May 2011 02:35:47 +0200 Subject: [PATCH 177/211] add changelog entry --- ChangeLog | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ChangeLog b/ChangeLog index cdf602203..d0b3b1a11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-05-16 Vladimir Serbinenko + + Fuloong video init support. + + * include/grub/vga.h (grub_vga_write_arx): inb monochrome address as + well. + (grub_vga_read_arx): New function. + * grub-core/video/sis315pro.c (GRUB_SIS315PRO_MMIO_SPACE): New + definition. + (framebuffer): New members io, mmioptr and mmiobase. + (read_sis_cmd): New function. + (write_sis_cmd): Likewise. + (grub_video_sis315pro_setup): Do the initialisation. Use 640x480 + rather than 640x400. + * grub-core/video/sis315_init.c: New file. + 2011-05-15 Vladimir Serbinenko * grub-core/bus/cs5536.c: Don't include grub/machine/kernel.h on From ff44d107adc5e85155b212211d4e0893d15da30c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 16 May 2011 02:39:25 +0200 Subject: [PATCH 178/211] Skip incorrect USB devices. * grub-core/bus/usb/usb.c (grub_usb_device_initialize): Fail if configcnt == 0. * include/grub/usb.h (grub_usb_err_t): New enum value GRUB_USB_ERR_BADDEVICE. --- ChangeLog | 9 +++++++++ grub-core/bus/usb/usb.c | 6 ++++++ include/grub/usb.h | 3 ++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d0b3b1a11..18a95a58e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-05-16 Vladimir Serbinenko + + Skip incorrect USB devices. + + * grub-core/bus/usb/usb.c (grub_usb_device_initialize): Fail if + configcnt == 0. + * include/grub/usb.h (grub_usb_err_t): New enum value + GRUB_USB_ERR_BADDEVICE. + 2011-05-16 Vladimir Serbinenko Fuloong video init support. diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c index 005d3bcf0..cde57ced8 100644 --- a/grub-core/bus/usb/usb.c +++ b/grub-core/bus/usb/usb.c @@ -185,6 +185,12 @@ grub_usb_device_initialize (grub_usb_device_t dev) for (i = 0; i < 8; i++) dev->config[i].descconf = NULL; + if (descdev->configcnt == 0) + { + err = GRUB_USB_ERR_BADDEVICE; + goto fail; + } + for (i = 0; i < descdev->configcnt; i++) { int pos; diff --git a/include/grub/usb.h b/include/grub/usb.h index 6f838e4f9..ee133dbf5 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -38,7 +38,8 @@ typedef enum GRUB_USB_ERR_BABBLE, GRUB_USB_ERR_TIMEOUT, GRUB_USB_ERR_BITSTUFF, - GRUB_USB_ERR_UNRECOVERABLE + GRUB_USB_ERR_UNRECOVERABLE, + GRUB_USB_ERR_BADDEVICE } grub_usb_err_t; typedef enum From 153a4b552de2dce36071cb3edd532330e67cd477 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 16 May 2011 08:50:21 +0200 Subject: [PATCH 179/211] * grub-core/bus/usb/usbhub.c (attach_root_port): Wait 10ms after enabling port. --- ChangeLog | 5 +++++ grub-core/bus/usb/usbhub.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 18a95a58e..fc4d68013 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-16 Vladimir Serbinenko + + * grub-core/bus/usb/usbhub.c (attach_root_port): Wait 10ms + after enabling port. + 2011-05-16 Vladimir Serbinenko Skip incorrect USB devices. diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c index 82bb2da1c..fff94a3fc 100644 --- a/grub-core/bus/usb/usbhub.c +++ b/grub-core/bus/usb/usbhub.c @@ -215,6 +215,8 @@ attach_root_port (struct grub_usb_hub *hub, int portno, return; hub->controller->dev->pending_reset = grub_get_time_ms () + 5000; + grub_millisleep (10); + /* Enable the port and create a device. */ dev = grub_usb_hub_add_dev (hub->controller, speed); hub->controller->dev->pending_reset = 0; From c8ecc840d7fa7111577ec3882623bb4b4f496e55 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 16 May 2011 08:51:55 +0200 Subject: [PATCH 180/211] * grub-core/bus/pci.c (grub_memalign_dma32): Always allocate in 64-byte blocks. --- ChangeLog | 5 +++++ grub-core/bus/pci.c | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fc4d68013..868391294 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-16 Vladimir Serbinenko + + * grub-core/bus/pci.c (grub_memalign_dma32): Always allocate in 64-byte + blocks. + 2011-05-16 Vladimir Serbinenko * grub-core/bus/usb/usbhub.c (attach_root_port): Wait 10ms diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c index 4212905f0..51006a20e 100644 --- a/grub-core/bus/pci.c +++ b/grub-core/bus/pci.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -30,7 +31,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); struct grub_pci_dma_chunk * grub_memalign_dma32 (grub_size_t align, grub_size_t size) { - void *ret = grub_memalign (align, size); + void *ret; + if (align < 64) + align = 64; + size = ALIGN_UP (size, align); + ret = grub_memalign (align, size); if (!ret) return 0; grub_arch_sync_dma_caches (ret, size); From 8e29b2ffe3c328d3b73fd7fc14ac4d6521154a08 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 16 May 2011 21:50:14 +0200 Subject: [PATCH 181/211] set id on arc disks --- grub-core/disk/arc/arcdisk.c | 65 +++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c index 62732c7ad..e8416634a 100644 --- a/grub-core/disk/arc/arcdisk.c +++ b/grub-core/disk/arc/arcdisk.c @@ -25,6 +25,59 @@ static grub_arc_fileno_t last_handle = 0; static char *last_path = NULL; +static int lnum = 0; + +struct arcdisk_hash_ent +{ + char *devpath; + int num; + struct arcdisk_hash_ent *next; +}; + +#define ARCDISK_HASH_SZ 8 +static struct arcdisk_hash_ent *arcdisk_hash[ARCDISK_HASH_SZ]; + +static int +arcdisk_hash_fn (const char *devpath) +{ + int hash = 0; + while (*devpath) + hash ^= *devpath++; + return (hash & (ARCDISK_HASH_SZ - 1)); +} + +static struct arcdisk_hash_ent * +arcdisk_hash_find (const char *devpath) +{ + struct arcdisk_hash_ent *p = arcdisk_hash[arcdisk_hash_fn (devpath)]; + + while (p) + { + if (!grub_strcmp (p->devpath, devpath)) + break; + p = p->next; + } + return p; +} + +static struct arcdisk_hash_ent * +arcdisk_hash_add (char *devpath) +{ + struct arcdisk_hash_ent *p; + struct arcdisk_hash_ent **head = &arcdisk_hash[arcdisk_hash_fn(devpath)]; + + p = grub_malloc (sizeof (*p)); + if (!p) + return NULL; + + p->devpath = devpath; + p->next = *head; + p->num = lnum++; + *head = p; + return p; +} + + static int grub_arcdisk_iterate (int (*hook_in) (const char *name)) { @@ -81,6 +134,8 @@ grub_arcdisk_open (const char *name, grub_disk_t disk) grub_err_t err; grub_arc_err_t r; struct grub_arc_fileinfo info; + struct arcdisk_hash_ent *hash; + if (grub_memcmp (name, "arc/", 4) != 0) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not arc device"); fullname = grub_malloc (2 * grub_strlen (name) + sizeof (RAW_SUFFIX)); @@ -114,6 +169,13 @@ grub_arcdisk_open (const char *name, grub_disk_t disk) grub_memcpy (optr, RAW_SUFFIX, sizeof (RAW_SUFFIX)); disk->data = fullname; grub_dprintf ("arcdisk", "opening %s\n", fullname); + + hash = arcdisk_hash_find (fullname); + if (!hash) + hash = arcdisk_hash_add (fullname); + if (!hash) + return grub_errno; + err = reopen (fullname); if (err) return err; @@ -147,7 +209,8 @@ grub_arcdisk_open (const char *name, grub_disk_t disk) } else disk->total_sectors = (info.end >> 9); - disk->id = 0; /* XXX */ + + disk->id = hash->num; return GRUB_ERR_NONE; } From 276ef9be21c60e2f0ff18daf7278de4a9f2ced9c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 16 May 2011 21:50:24 +0200 Subject: [PATCH 182/211] Fix install message --- util/grub-install.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index 0e0dfe920..ad6ea1037 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -621,8 +621,7 @@ elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${pla fi elif [ x"${target_cpu}-${platform}" = xmips-arc ]; then dvhtool -d "${install_device}" --unix-to-vh "{grubdir}/core.${imgext}" grub - echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" - + echo "You will have to set SystemPartition and OSLoader manually." elif [ x"$platform" = xefi ]; then cp "${grubdir}/core.${imgext}" "${efidir}/${efi_file}" # For old macs. Suggested by Peter Jones. From b6296b3f9e4dcf24dddc6e1dc3a4f1a06b50d850 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 09:18:53 +0200 Subject: [PATCH 183/211] Add missing ChngeLog line --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 088de8937..815df4dd8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -104,6 +104,7 @@ to 6. * util/grub-install.in: Run dvhtool on ARC. * util/grub-mkimage.c (image_targets): Add mips-arc. + (generate_image): Handle ECOFF output for mips-arc. 2011-05-16 Vladimir Serbinenko From 1b6656d360d0bb6814b68ade969e04e82ad121d6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 14:04:49 +0200 Subject: [PATCH 184/211] Revert changes to cache_flush.S --- grub-core/kern/mips/cache_flush.S | 4 ---- 1 file changed, 4 deletions(-) diff --git a/grub-core/kern/mips/cache_flush.S b/grub-core/kern/mips/cache_flush.S index 305a8b401..a352fd8ba 100644 --- a/grub-core/kern/mips/cache_flush.S +++ b/grub-core/kern/mips/cache_flush.S @@ -1,6 +1,3 @@ - - /* Qemu doesn't emulate caches. Oh boy. */ -#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS move $t2, $a0 addu $t3, $a0, $a1 srl $t2, $t2, 5 @@ -24,4 +21,3 @@ bne $t1, $zero, 2b addiu $t0, $t0, 0x4 sync -#endif \ No newline at end of file From b38c1d1442aec530c9faf80579ebf0cb8122adb4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 14:05:52 +0200 Subject: [PATCH 185/211] Fix -O for qemu --- util/grub-mkimage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 480521cd6..5f35c1da0 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -444,7 +444,7 @@ struct image_target_desc image_targets[] = }, { .dirname = "mips-qemu_mips", - .names = { "mips-qemu_mips-elf", NULL }, + .names = { "mipsel-qemu_mips-elf", NULL }, .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_LOONGSON_ELF, From a228ec103a07815c4e08021f946d10b6fb15ac5b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 14:35:55 +0200 Subject: [PATCH 186/211] enable ATA on qemu-mips --- grub-core/Makefile.core.def | 2 ++ grub-core/disk/ata.c | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 48809a65d..1c0b530a1 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -856,12 +856,14 @@ module = { name = ata; common = disk/ata.c; enable = pci; + enable = mips_qemu_mips; }; module = { name = ata_pthru; common = disk/ata_pthru.c; enable = pci; + enable = mips_qemu_mips; }; module = { diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 391ccb9a2..12e70d91b 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -22,9 +22,13 @@ #include #include #include +#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS #include -#include #include +#else +#define GRUB_MACHINE_PCI_IO_BASE 0xb4000000 +#endif +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -409,6 +413,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) return 0; } +#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS static int NESTED_FUNC_ATTR grub_ata_pciinit (grub_pci_device_t dev, grub_pci_id_t pciid) @@ -524,6 +529,21 @@ grub_ata_initialize (void) grub_pci_iterate (grub_ata_pciinit); return 0; } +#else +static grub_err_t +grub_ata_initialize (void) +{ + int i; + for (i = 0; i < 2; i++) + { + grub_ata_device_initialize (i, 0, grub_ata_ioaddress[i], + grub_ata_ioaddress2[i]); + grub_ata_device_initialize (i, 1, grub_ata_ioaddress[i], + grub_ata_ioaddress2[i]); + } + return 0; +} +#endif static void grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector, From dc16af0369c45d8987c7a65fecea962a0b2e6786 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 15:34:40 +0200 Subject: [PATCH 187/211] make linux loader work on qemu-mips --- grub-core/loader/mips/linux.c | 68 ++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index e0a0e7c98..722be36a9 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -27,6 +27,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -53,12 +54,16 @@ static grub_size_t linux_size; static struct grub_relocator *relocator; static grub_uint8_t *playground; static grub_addr_t target_addr, entry_addr; +#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS +static char *params; +#else static int linux_argc; static grub_off_t argv_off; #ifdef GRUB_MACHINE_MIPS_LOONGSON static grub_off_t envp_off; #endif static grub_off_t rd_addr_arg_off, rd_size_arg_off; +#endif static int initrd_loaded = 0; static grub_err_t @@ -66,8 +71,26 @@ grub_linux_boot (void) { struct grub_relocator32_state state; + grub_memset (&state, 0, sizeof (state)); + /* Boot the kernel. */ state.gpr[1] = entry_addr; + +#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS + { + grub_err_t err; + grub_relocator_chunk_t ch; + + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + ((16 << 20) - 256), + grub_strlen (params) + 1); + if (err) + return err; + grub_strcpy (get_virtual_current_address (ch), params); + } +#endif + +#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS state.gpr[4] = linux_argc; state.gpr[5] = target_addr + argv_off; #ifdef GRUB_MACHINE_MIPS_LOONGSON @@ -76,6 +99,7 @@ grub_linux_boot (void) state.gpr[6] = 0; #endif state.gpr[7] = 0; +#endif state.jumpreg = 1; grub_relocator32_boot (relocator, state); @@ -88,6 +112,11 @@ grub_linux_unload (void) grub_relocator_unload (relocator); grub_dl_unref (my_mod); +#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS + grub_free (params); + params = 0; +#endif + loaded = 0; return GRUB_ERR_NONE; @@ -207,11 +236,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_elf_t elf = 0; - int i; int size; void *extra = NULL; +#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS + int i; grub_uint32_t *linux_argv; char *linux_args; +#endif grub_err_t err; #ifdef GRUB_MACHINE_MIPS_LOONGSON char *linux_envs; @@ -236,6 +267,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_loader_unset (); loaded = 0; +#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS + size = 0; +#else /* For arguments. */ linux_argc = argc; #ifdef GRUB_MACHINE_MIPS_LOONGSON @@ -268,6 +302,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4) + ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4) + ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4); +#endif if (grub_elf_is_elf32 (elf)) err = grub_linux_load32 (elf, &extra, size); @@ -282,6 +317,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (err) return err; +#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS + /* Create kernel command line. */ + size = grub_loader_cmdline_size(argc, argv); + params = grub_malloc (size + sizeof (LINUX_IMAGE)); + if (! params) + { + grub_linux_unload (); + return grub_errno; + } + + grub_memcpy (params, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + grub_create_loader_cmdline (argc, argv, params + sizeof (LINUX_IMAGE) - 1, + size); +#else linux_argv = extra; argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground; extra = linux_argv + (linux_argc + 1 + 2); @@ -362,6 +411,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); linux_envp[4] = 0; +#endif #endif grub_loader_set (grub_linux_boot, grub_linux_unload, 1); @@ -425,6 +475,21 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } +#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS + { + char *tmp; + tmp = grub_xasprintf ("%s rd_start=0x%" PRIxGRUB_ADDR + " rd_size=0x%" PRIxGRUB_ADDR, params, + initrd_dest, size); + if (!tmp) + { + grub_file_close (file); + return grub_errno; + } + grub_free (params); + params = tmp; + } +#else grub_snprintf ((char *) playground + rd_addr_arg_off, sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%llx", (unsigned long long) initrd_dest); @@ -438,6 +503,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), ((grub_uint32_t *) (playground + argv_off))[linux_argc] = target_addr + rd_size_arg_off; linux_argc++; +#endif initrd_loaded = 1; From 90f7ac192fad8a204c1456dd90c239043ce70d91 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 18:39:32 +0200 Subject: [PATCH 188/211] * grub-core/kern/mips/startup.S (grub_arch_cpuclock): Move to the right place. --- ChangeLog | 5 +++++ grub-core/kern/mips/startup.S | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index c0b2e0ce3..5cd5d0b8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-17 Vladimir Serbinenko + + * grub-core/kern/mips/startup.S (grub_arch_cpuclock): Move to the right + place. + 2011-05-17 Vladimir Serbinenko Reenable qemu-mips port. diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 58acb00f3..1472aaf8c 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -51,18 +51,16 @@ VARIABLE(grub_prefix) */ . = _start + GRUB_KERNEL_MACHINE_PREFIX_END -VARIABLE (grub_arch_cpuclock) - .long 0 -#ifdef GRUB_MACHINE_MIPS_LOONGSON VARIABLE (grub_arch_busclock) .long 0 +VARIABLE (grub_arch_cpuclock) + .long 0 VARIABLE (grub_arch_memsize) .long 0 VARIABLE (grub_arch_highmemsize) .long 0 VARIABLE (grub_arch_machine) .long GRUB_ARCH_MACHINE_FULOONG -#endif cont: /* Save our base. */ move $s0, $ra From 24c9143ae3b22a54b9d26e5ef823b394f135dd72 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 17 May 2011 18:00:31 +0100 Subject: [PATCH 189/211] * Makefile.util.def (grub-bin2h): Don't install. * docs/man/grub-bin2h.h2m: Remove. --- ChangeLog | 5 +++++ Makefile.util.def | 2 +- docs/man/grub-bin2h.h2m | 2 -- 3 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 docs/man/grub-bin2h.h2m diff --git a/ChangeLog b/ChangeLog index 5cd5d0b8e..47d23d811 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-17 Colin Watson + + * Makefile.util.def (grub-bin2h): Don't install. + * docs/man/grub-bin2h.h2m: Remove. + 2011-05-17 Vladimir Serbinenko * grub-core/kern/mips/startup.S (grub_arch_cpuclock): Move to the right diff --git a/Makefile.util.def b/Makefile.util.def index 60ad78217..380c939b9 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -114,7 +114,7 @@ program = { ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; - mansection = 1; + installdir = noinst; }; program = { diff --git a/docs/man/grub-bin2h.h2m b/docs/man/grub-bin2h.h2m deleted file mode 100644 index ef463f3d1..000000000 --- a/docs/man/grub-bin2h.h2m +++ /dev/null @@ -1,2 +0,0 @@ -[NAME] -grub-bin2h \- convert a binary file to a C header From 3ca2b466459ffe724e8f8e1c450a619710de44a4 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 17 May 2011 18:03:59 +0100 Subject: [PATCH 190/211] * util/grub-fstest.c (cmd_cat): New function. (fstest): Handle CMD_CAT. (options): Add cat. (argp_parser): Handle cat. --- ChangeLog | 7 +++++++ util/grub-fstest.c | 44 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47d23d811..4f17525b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-05-17 Colin Watson + + * util/grub-fstest.c (cmd_cat): New function. + (fstest): Handle CMD_CAT. + (options): Add cat. + (argp_parser): Handle cat. + 2011-05-17 Colin Watson * Makefile.util.def (grub-bin2h): Don't install. diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 293bdf74a..f253a96f6 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -54,12 +54,15 @@ execute_command (char *name, int n, char **args) return (cmd->func) (cmd, n, args); } -#define CMD_LS 1 -#define CMD_CP 2 -#define CMD_CMP 3 -#define CMD_HEX 4 -#define CMD_CRC 6 -#define CMD_BLOCKLIST 7 +enum { + CMD_LS = 1, + CMD_CP, + CMD_CAT, + CMD_CMP, + CMD_HEX, + CMD_CRC, + CMD_BLOCKLIST +}; #define BUF_SIZE 32256 @@ -182,6 +185,26 @@ cmd_cp (char *src, char *dest) fclose (ff); } +static void +cmd_cat (char *src) +{ + auto int cat_hook (grub_off_t ofs, char *buf, int len); + int cat_hook (grub_off_t ofs, char *buf, int len) + { + (void) ofs; + + if ((int) fwrite (buf, 1, len, stdout) != len) + { + grub_util_error (_("write error")); + return 1; + } + + return 0; + } + + read_file (src, cat_hook); +} + static void cmd_cmp (char *src, char *dest) { @@ -321,6 +344,9 @@ fstest (int n, char **args) case CMD_CP: cmd_cp (args[0], args[1]); break; + case CMD_CAT: + cmd_cat (args[0]); + break; case CMD_CMP: cmd_cmp (args[0], args[1]); break; @@ -356,6 +382,7 @@ static struct argp_option options[] = { {0, 0, 0 , OPTION_DOC, N_("Commands:"), 1}, {N_("ls PATH"), 0, 0 , OPTION_DOC, N_("List files in PATH."), 1}, {N_("cp FILE LOCAL"), 0, 0, OPTION_DOC, N_("Copy FILE to local file LOCAL."), 1}, + {N_("cat FILE"), 0, 0 , OPTION_DOC, N_("Copy FILE to standard output."), 1}, {N_("cmp FILE LOCAL"), 0, 0, OPTION_DOC, N_("Compare FILE with local file LOCAL."), 1}, {N_("hex FILE"), 0, 0 , OPTION_DOC, N_("Hex dump FILE."), 1}, {N_("crc FILE"), 0, 0 , OPTION_DOC, N_("Get crc32 checksum of FILE."), 1}, @@ -468,6 +495,11 @@ argp_parser (int key, char *arg, struct argp_state *state) cmd = CMD_CP; nparm = 2; } + else if (!grub_strcmp (arg, "cat")) + { + cmd = CMD_CAT; + nparm = 1; + } else if (!grub_strcmp (arg, "cmp")) { cmd = CMD_CMP; From d064b83056698964cd6b59c6334d107a55379f46 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 17 May 2011 18:10:29 +0100 Subject: [PATCH 191/211] * util/grub.d/20_linux_xen.in: Honour GRUB_CMDLINE_LINUX_XEN_REPLACE and GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT, which replace GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT (complementing the existing options which append). * docs/grub.texi (Simple configuration): Document new options. Reported by: Ian Jackson. Fixes Debian bug #617538. --- ChangeLog | 9 +++++++++ docs/grub.texi | 10 ++++++++-- util/grub.d/20_linux_xen.in | 8 ++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f17525b6..ab710f5fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-05-17 Colin Watson + + * util/grub.d/20_linux_xen.in: Honour GRUB_CMDLINE_LINUX_XEN_REPLACE + and GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT, which replace + GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT (complementing the + existing options which append). + * docs/grub.texi (Simple configuration): Document new options. + Reported by: Ian Jackson. Fixes Debian bug #617538. + 2011-05-17 Colin Watson * util/grub-fstest.c (cmd_cat): New function. diff --git a/docs/grub.texi b/docs/grub.texi index b11e3836f..7e28d457a 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1169,8 +1169,14 @@ NetBSD. @item GRUB_CMDLINE_XEN @itemx GRUB_CMDLINE_XEN_DEFAULT -As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for -Linux and Xen. +The values of these options are appended to the values of +@samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT} for Linux +and Xen menu entries. + +@item GRUB_CMDLINE_LINUX_XEN_REPLACE +@item GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT +The values of these options replace the values of @samp{GRUB_CMDLINE_LINUX} +and @samp{GRUB_CMDLINE_LINUX_DEFAULT} for Linux and Xen menu entries. @item GRUB_DISABLE_LINUX_UUID Normally, @command{grub-mkconfig} will generate menu entries that use diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index a9007603d..083391c40 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -51,6 +51,14 @@ else LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} fi +# Allow overriding GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT. +if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE}" ]; then + GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX_XEN_REPLACE}" +fi +if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" ]; then + GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" +fi + if [ "x`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2>/dev/null || true`" = xbtrfs ]; then rootsubvol="`make_system_path_relative_to_its_root /`" rootsubvol="${rootsubvol#/}" From 5d420cd9833ce99500222ceefa1addbffb6a45b7 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 17 May 2011 18:13:12 +0100 Subject: [PATCH 192/211] * .bzrignore: Remove grub-dumpbios. --- .bzrignore | 1 - ChangeLog | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.bzrignore b/.bzrignore index 55cbdaeeb..668d060ca 100644 --- a/.bzrignore +++ b/.bzrignore @@ -31,7 +31,6 @@ genkernsyms.sh gensymlist.sh gentrigtables grub-bin2h -grub-dumpbios grub-editenv grub-emu grub_emu_init.c diff --git a/ChangeLog b/ChangeLog index ab710f5fb..ded0469a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-05-17 Colin Watson + + * .bzrignore: Remove grub-dumpbios. + 2011-05-17 Colin Watson * util/grub.d/20_linux_xen.in: Honour GRUB_CMDLINE_LINUX_XEN_REPLACE From 566a191715b3a91a7f5efd7e44e203620c513310 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 19:32:51 +0200 Subject: [PATCH 193/211] Prevent potential loss of memory map by overwrite on qemu-mips. * grub-core/boot/mips/startup_raw.S [GRUB_MACHINE_MIPS_QEMU_MIPS]: Save ram size in $s4. * grub-core/kern/mips/qemu_mips/init.c (RAMSIZE): Removed. All users changed to grub_arch_memsize. * grub-core/kern/mips/startup.S (grub_arch_machine): Restrict to Loongson. [GRUB_MACHINE_MIPS_QEMU_MIPS]: Save grub_arch_memsize. * grub-core/loader/mips/linux.c (grub_linux_boot): Pass memory size. * include/grub/mips/qemu_mips/memory.h (grub_arch_memsize): New external variable. --- ChangeLog | 15 +++++++++++++++ grub-core/boot/mips/startup_raw.S | 5 +++++ grub-core/kern/mips/qemu_mips/init.c | 6 ++---- grub-core/kern/mips/startup.S | 8 ++++++++ grub-core/loader/mips/linux.c | 14 +++++++++++--- include/grub/mips/qemu_mips/memory.h | 3 +++ 6 files changed, 44 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index ded0469a3..d1f01e727 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2011-05-17 Vladimir Serbinenko + + Prevent potential loss of memory map by overwrite on qemu-mips. + + * grub-core/boot/mips/startup_raw.S [GRUB_MACHINE_MIPS_QEMU_MIPS]: + Save ram size in $s4. + * grub-core/kern/mips/qemu_mips/init.c (RAMSIZE): Removed. + All users changed to grub_arch_memsize. + * grub-core/kern/mips/startup.S (grub_arch_machine): Restrict to + Loongson. + [GRUB_MACHINE_MIPS_QEMU_MIPS]: Save grub_arch_memsize. + * grub-core/loader/mips/linux.c (grub_linux_boot): Pass memory size. + * include/grub/mips/qemu_mips/memory.h (grub_arch_memsize): New + external variable. + 2011-05-17 Colin Watson * .bzrignore: Remove grub-dumpbios. diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index e69de26c2..65a2dd59e 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -50,6 +50,11 @@ codestart: /* Parse arguments. Has to be done before relocation. So need to do it in asm. */ +#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS + lui $t0, %hi (((16 << 20) - 264) | 0x80000000) + lw $s4, %lo (((16 << 20) - 264) | 0x80000000) ($t0) +#endif + #ifdef GRUB_MACHINE_MIPS_LOONGSON move $s2, $zero move $s3, $zero diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index b3155eab5..e426b833d 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -10,8 +10,6 @@ #include #include -#define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264)) - extern void grub_serial_init (void); extern void grub_terminfo_init (void); @@ -24,7 +22,7 @@ grub_machine_init (void) grub_arch_cpuclock = 64000000; modend = grub_modules_get_end (); - grub_mm_init_region ((void *) modend, RAMSIZE + grub_mm_init_region ((void *) modend, grub_arch_memsize - (modend - GRUB_ARCH_LOWMEMVSTART)); grub_install_get_time_ms (grub_rtc_get_time_ms); @@ -59,6 +57,6 @@ grub_reboot (void) grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook) { - hook (0, RAMSIZE, GRUB_MEMORY_AVAILABLE); + hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE); return GRUB_ERR_NONE; } diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 1472aaf8c..2654d744e 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -59,12 +59,20 @@ VARIABLE (grub_arch_memsize) .long 0 VARIABLE (grub_arch_highmemsize) .long 0 +#ifdef GRUB_MACHINE_MIPS_LOONGSON VARIABLE (grub_arch_machine) .long GRUB_ARCH_MACHINE_FULOONG +#endif cont: /* Save our base. */ move $s0, $ra +#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS + lui $t1, %hi(grub_arch_busclock) + addiu $t1, %lo(grub_arch_busclock) + sw $s4, 8($t1) +#endif + #ifdef GRUB_MACHINE_MIPS_LOONGSON lui $t1, %hi(grub_arch_busclock) addiu $t1, %lo(grub_arch_busclock) diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 722be36a9..64c4a0531 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -80,13 +80,21 @@ grub_linux_boot (void) { grub_err_t err; grub_relocator_chunk_t ch; + grub_uint32_t *memsize; + grub_uint32_t *magic; + char *str; err = grub_relocator_alloc_chunk_addr (relocator, &ch, - ((16 << 20) - 256), - grub_strlen (params) + 1); + ((16 << 20) - 264), + grub_strlen (params) + 1 + 8); if (err) return err; - grub_strcpy (get_virtual_current_address (ch), params); + memsize = get_virtual_current_address (ch); + magic = memsize + 1; + *memsize = grub_mmap_get_lower (); + *magic = 0x12345678; + str = (char *) (magic + 1); + grub_strcpy (str, params); } #endif diff --git a/include/grub/mips/qemu_mips/memory.h b/include/grub/mips/qemu_mips/memory.h index 7a7ff143e..48a9b69f0 100644 --- a/include/grub/mips/qemu_mips/memory.h +++ b/include/grub/mips/qemu_mips/memory.h @@ -29,6 +29,9 @@ #define GRUB_MACHINE_MEMORY_USABLE 0x81000000 #ifndef ASM_FILE + +extern grub_uint32_t grub_arch_memsize; + static inline grub_err_t grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), grub_uint64_t size __attribute__ ((unused)), From b772baedcd8ef2a995f4bb0fc8ebc9157c21e9b7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 21:15:54 +0200 Subject: [PATCH 194/211] Reduce memory footprint on SGI by putting modules before the kernel as opposed to after. * grub-core/Makefile.core.def (kernel): Increase linking address. (none_decompress): Likewise. (xz_decompress): Likewise. * grub-core/boot/mips/startup_raw.S: Use prewritten uncompression address. * grub-core/kern/mips/arc/init.c (grub_machine_init): Handle memory layout change. (grub_arch_modules_addr): New function. * grub-core/kern/mips/init.c (grub_arch_modules_addr): Moved from here... * grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): .. here * grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): ... and here. * grub-core/kern/mips/startup.S (total_size): Rename to ... (grub_total_modules_size): ... this. Make global. [GRUB_MACHINE_ARC]: Don't attempt to move modules out of the bss. * include/grub/offsets.h (GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR): New definition. (GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR): Likewise. (GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR): Likewise. (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR): Likewise. (GRUB_KERNEL_MIPS_ARC_LINK_ADDR): Increased. * util/grub-mkimage.c (image_target_desc): New flag PLATFORM_FLAGS_MODULES_BEFORE_KERNEL. (image_targets): Set PLATFORM_FLAGS_MODULES_BEFORE_KERNEL on mips-arc. (generate_image): Handle images with modules before kernel. --- ChangeLog | 31 ++++++++++++ grub-core/Makefile.core.def | 6 +-- grub-core/boot/mips/startup_raw.S | 6 ++- grub-core/kern/mips/arc/init.c | 14 +++++- grub-core/kern/mips/init.c | 8 ---- grub-core/kern/mips/loongson/init.c | 7 +++ grub-core/kern/mips/qemu_mips/init.c | 8 ++++ grub-core/kern/mips/startup.S | 4 +- include/grub/offsets.h | 6 ++- util/grub-mkimage.c | 70 ++++++++++++++++++++-------- 10 files changed, 123 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index d1f01e727..bf7d7d110 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2011-05-17 Vladimir Serbinenko + + Reduce memory footprint on SGI by putting modules before the kernel + as opposed to after. + + * grub-core/Makefile.core.def (kernel): Increase linking address. + (none_decompress): Likewise. + (xz_decompress): Likewise. + * grub-core/boot/mips/startup_raw.S: Use prewritten uncompression + address. + * grub-core/kern/mips/arc/init.c (grub_machine_init): Handle memory + layout change. + (grub_arch_modules_addr): New function. + * grub-core/kern/mips/init.c (grub_arch_modules_addr): Moved from here... + * grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): .. here + * grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): ... and + here. + * grub-core/kern/mips/startup.S (total_size): Rename to ... + (grub_total_modules_size): ... this. Make global. + [GRUB_MACHINE_ARC]: Don't attempt to move modules out of the bss. + * include/grub/offsets.h (GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR): + New definition. + (GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR): Likewise. + (GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR): Likewise. + (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR): Likewise. + (GRUB_KERNEL_MIPS_ARC_LINK_ADDR): Increased. + * util/grub-mkimage.c (image_target_desc): New flag + PLATFORM_FLAGS_MODULES_BEFORE_KERNEL. + (image_targets): Set PLATFORM_FLAGS_MODULES_BEFORE_KERNEL on mips-arc. + (generate_image): Handle images with modules before kernel. + 2011-05-17 Vladimir Serbinenko Prevent potential loss of memory map by overwrite on qemu-mips. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 1c0b530a1..c717167cb 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -41,7 +41,7 @@ kernel = { mips_loongson_ldflags = '-Wl,-Ttext,0x80200000'; powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; - mips_arc_ldflags = '-Wl,-Ttext,0x8a000000'; + mips_arc_ldflags = '-Wl,-Ttext,0x8bd00000'; mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000'; mips_loongson_cppflags = '-DUSE_ASCII_FAILBACK'; @@ -324,7 +324,7 @@ image = { objcopyflags = '-O binary'; mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; - mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x89f00000'; + mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000'; ldadd = '-lgcc'; cflags = '-static-libgcc'; enable = mips; @@ -340,7 +340,7 @@ image = { objcopyflags = '-O binary'; mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; - mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x89f00000'; + mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000'; ldadd = '-lgcc'; cflags = '-static-libgcc'; enable = mips; diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index 65a2dd59e..e6dfadaf9 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -44,6 +44,9 @@ compressed_size: . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE uncompressed_size: .long 0 + . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR +uncompressed_addr: + .long 0 codestart: /* Save our base. */ move $s0, $ra @@ -221,8 +224,7 @@ cmdlinedone: subu $a0, $a0, $t0 addu $a0, $a0, $s0 - lui $a1, %hi(GRUB_MACHINE_LINK_ADDR) - addiu $a1, %lo(GRUB_MACHINE_LINK_ADDR) + lw $a1, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0) lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) lw $a3, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0) move $s1, $a1 diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index 8ee965d74..514b481f6 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -124,6 +124,8 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) } } +extern grub_uint32_t grub_total_modules_size; + void grub_machine_init (void) { @@ -148,8 +150,10 @@ grub_machine_init (void) start = ((grub_uint64_t) cur->start_page) << 12; end = ((grub_uint64_t) cur->num_pages) << 12; end += start; - if ((grub_uint64_t) end > (GRUB_KERNEL_MIPS_ARC_LINK_ADDR & 0x1fffffff)) - end = (GRUB_KERNEL_MIPS_ARC_LINK_ADDR & 0x1fffffff); + if ((grub_uint64_t) end > ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR + - grub_total_modules_size) & 0x1fffffff)) + end = ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size) + & 0x1fffffff); if (end > start) grub_mm_init_region ((void *) (grub_addr_t) (start | 0x80000000), end - start); @@ -160,6 +164,12 @@ grub_machine_init (void) grub_arcdisk_init (); } +grub_addr_t +grub_arch_modules_addr (void) +{ + return GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size; +} + void grub_machine_fini (void) { diff --git a/grub-core/kern/mips/init.c b/grub-core/kern/mips/init.c index 3b08d5606..bfa08f56a 100644 --- a/grub-core/kern/mips/init.c +++ b/grub-core/kern/mips/init.c @@ -42,11 +42,3 @@ grub_machine_set_prefix (void) { grub_env_set ("prefix", grub_prefix); } - -extern char _end[]; - -grub_addr_t -grub_arch_modules_addr (void) -{ - return (grub_addr_t) _end; -} diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index f0f5c5874..bcef391b9 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -257,3 +257,10 @@ grub_reboot (void) while (1); } +extern char _end[]; + +grub_addr_t +grub_arch_modules_addr (void) +{ + return (grub_addr_t) _end; +} diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index e426b833d..2180b347a 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -60,3 +60,11 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE); return GRUB_ERR_NONE; } + +extern char _end[]; + +grub_addr_t +grub_arch_modules_addr (void) +{ + return (grub_addr_t) _end; +} diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 2654d744e..6220a8c33 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -37,7 +37,7 @@ start: nop . = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE -total_module_size: +VARIABLE(grub_total_modules_size) .long 0 . = _start + GRUB_KERNEL_MACHINE_PREFIX @@ -84,6 +84,7 @@ cont: #endif /* Move the modules out of BSS. */ +#ifndef GRUB_MACHINE_ARC lui $t2, %hi(__bss_start) addiu $t2, %lo(__bss_start) @@ -113,6 +114,7 @@ modulesmovcont: b modulesmovcont addiu $t3, $t3, -1 modulesmovdone: +#endif /* Clean BSS. */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 40c8a016b..af724096d 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -106,6 +106,7 @@ #define GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE 0x8 #define GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE 0xc +#define GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE 0x08 #define GRUB_KERNEL_MIPS_LOONGSON_PREFIX 0x0c @@ -115,16 +116,18 @@ #define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN 32 #define GRUB_KERNEL_MIPS_QEMU_MIPS_COMPRESSED_SIZE 0x8 #define GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE 0xc +#define GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE 0x08 #define GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX 0x0c #define GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END 0x54 -#define GRUB_KERNEL_MIPS_ARC_LINK_ADDR 0x8a000000 +#define GRUB_KERNEL_MIPS_ARC_LINK_ADDR 0x8bd00000 #define GRUB_KERNEL_MIPS_ARC_LINK_ALIGN 32 #define GRUB_KERNEL_MIPS_ARC_COMPRESSED_SIZE 0x8 #define GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_SIZE 0xc +#define GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE 0x08 #define GRUB_KERNEL_MIPS_ARC_PREFIX 0x0c @@ -187,6 +190,7 @@ #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _KERNEL_IMAGE_SIZE) #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _COMPRESSED_SIZE) #define GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _UNCOMPRESSED_SIZE) +#define GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _UNCOMPRESSED_ADDR) #define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _PREFIX) #define GRUB_KERNEL_MACHINE_PREFIX_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _PREFIX_END) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 5f35c1da0..5ae744a8e 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -73,7 +73,8 @@ struct image_target_desc { PLATFORM_FLAGS_NONE = 0, PLATFORM_FLAGS_LZMA = 1, - PLATFORM_FLAGS_DECOMPRESSORS = 2 + PLATFORM_FLAGS_DECOMPRESSORS = 2, + PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4, } flags; unsigned prefix; unsigned prefix_end; @@ -426,7 +427,8 @@ struct image_target_desc image_targets[] = .voidp_sizeof = 4, .bigendian = 1, .id = IMAGE_MIPS_ARC, - .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .flags = (PLATFORM_FLAGS_DECOMPRESSORS + | PLATFORM_FLAGS_MODULES_BEFORE_KERNEL), .prefix = GRUB_KERNEL_MIPS_ARC_PREFIX, .prefix_end = GRUB_KERNEL_MIPS_ARC_PREFIX_END, .raw_size = 0, @@ -781,27 +783,47 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_error (_("prefix is too long")); strcpy (kernel_img + image_target->prefix, prefix); + if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + && (image_target->total_module_size != TARGET_NO_FIELD)) + *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + memmove (kernel_img + total_module_size, kernel_img, kernel_size); + if (image_target->voidp_sizeof == 8) { /* Fill in the grub_module_info structure. */ struct grub_module_info64 *modinfo; - modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + modinfo = (struct grub_module_info64 *) kernel_img; + else + modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size); memset (modinfo, 0, sizeof (struct grub_module_info64)); modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64)); modinfo->size = grub_host_to_target_addr (total_module_size); - offset = kernel_size + sizeof (struct grub_module_info64); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + offset = sizeof (struct grub_module_info64); + else + offset = kernel_size + sizeof (struct grub_module_info64); } else { /* Fill in the grub_module_info structure. */ struct grub_module_info32 *modinfo; - modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + modinfo = (struct grub_module_info32 *) kernel_img; + else + modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size); memset (modinfo, 0, sizeof (struct grub_module_info32)); modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32)); modinfo->size = grub_host_to_target_addr (total_module_size); - offset = kernel_size + sizeof (struct grub_module_info32); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + offset = sizeof (struct grub_module_info32); + else + offset = kernel_size + sizeof (struct grub_module_info32); } for (p = path_list; p; p = p->next) @@ -852,26 +874,27 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], offset += config_size; } - if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) - && (image_target->total_module_size != TARGET_NO_FIELD)) - *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) - = grub_host_to_target32 (total_module_size); - grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); compress_kernel (image_target, kernel_img, kernel_size + total_module_size, &core_img, &core_size, comp); + free (kernel_img); + + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + kernel_img = core_img + total_module_size; + else + kernel_img = core_img; grub_util_info ("the core size is 0x%x", core_size); if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) && image_target->total_module_size != TARGET_NO_FIELD) - *((grub_uint32_t *) (core_img + image_target->total_module_size)) + *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) = grub_host_to_target32 (total_module_size); if (image_target->kernel_image_size != TARGET_NO_FIELD) - *((grub_uint32_t *) (core_img + image_target->kernel_image_size)) + *((grub_uint32_t *) (kernel_img + image_target->kernel_image_size)) = grub_host_to_target32 (kernel_size); if (image_target->compressed_size != TARGET_NO_FIELD) - *((grub_uint32_t *) (core_img + image_target->compressed_size)) + *((grub_uint32_t *) (kernel_img + image_target->compressed_size)) = grub_host_to_target32 (core_size - image_target->raw_size); /* If we included a drive in our prefix, let GRUB know it doesn't have to @@ -879,9 +902,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (image_target->install_dos_part != TARGET_NO_FIELD && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') { - *((grub_int32_t *) (core_img + image_target->install_dos_part)) + *((grub_int32_t *) (kernel_img + image_target->install_dos_part)) = grub_host_to_target32 (-2); - *((grub_int32_t *) (core_img + image_target->install_bsd_part)) + *((grub_int32_t *) (kernel_img + image_target->install_bsd_part)) = grub_host_to_target32 (-2); } @@ -915,6 +938,13 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE)) = grub_host_to_target32 (kernel_size + total_module_size); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR)) + = grub_host_to_target_addr (image_target->link_addr - total_module_size); + else + *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR)) + = grub_host_to_target_addr (image_target->link_addr); + full_size = core_size + decompress_size; full_img = xmalloc (full_size); @@ -1199,7 +1229,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], rom_img = xmalloc (rom_size); memset (rom_img, 0, rom_size); - *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + *((grub_int32_t *) (kernel_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) = grub_host_to_target32 ((grub_uint32_t) -rom_size); memcpy (rom_img, core_img, core_size); @@ -1380,8 +1410,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t program_size; program_size = ALIGN_ADDR (core_size); - target_addr = image_target->link_addr - ALIGN_UP(program_size, 1048576) - - (1 << 20); + target_addr = (image_target->link_addr + - ALIGN_UP(total_module_size + core_size, 1048576) + - (1 << 20)); ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section)); grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section)); @@ -1553,7 +1584,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], } grub_util_write_image (core_img, core_size, out); - free (kernel_img); free (core_img); free (kernel_path); From 35341bbc9644eb17ae08e5ccbc52c691cc8357fb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 21:40:35 +0200 Subject: [PATCH 195/211] Avoid unnecessary copying on MIPS. * grub-core/boot/decompressor/none.c (grub_decompress_core): Exit early if src == dest. * util/grub-mkimage.c (generate_image): Arange for src == dest if compression is none. --- ChangeLog | 9 +++++++++ grub-core/boot/decompressor/none.c | 3 +++ util/grub-mkimage.c | 21 +++++++++++++++------ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf7d7d110..2d6a02d08 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-05-17 Vladimir Serbinenko + + Avoid unnecessary copying on MIPS. + + * grub-core/boot/decompressor/none.c (grub_decompress_core): Exit + early if src == dest. + * util/grub-mkimage.c (generate_image): Arange for src == dest if + compression is none. + 2011-05-17 Vladimir Serbinenko Reduce memory footprint on SGI by putting modules before the kernel diff --git a/grub-core/boot/decompressor/none.c b/grub-core/boot/decompressor/none.c index 44f56ce90..911e861e3 100644 --- a/grub-core/boot/decompressor/none.c +++ b/grub-core/boot/decompressor/none.c @@ -25,6 +25,9 @@ grub_decompress_core (void *src, void *dest, unsigned long n, char *d = (char *) dest; const char *s = (const char *) src; + if (d == s) + return; + if (d < s) while (n--) *d++ = *s++; diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 5ae744a8e..2003a86d2 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -736,6 +736,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_uint64_t start_address; void *rel_section; grub_size_t reloc_size, align; + size_t decompress_size; if (comp == COMPRESSION_AUTO) comp = image_target->default_compression; @@ -913,7 +914,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *full_img; size_t full_size; char *decompress_path, *decompress_img; - size_t decompress_size; const char *name; switch (comp) @@ -1410,9 +1410,13 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t program_size; program_size = ALIGN_ADDR (core_size); - target_addr = (image_target->link_addr - - ALIGN_UP(total_module_size + core_size, 1048576) - - (1 << 20)); + if (comp == COMPRESSION_NONE) + target_addr = (image_target->link_addr + - total_module_size - decompress_size); + else + target_addr = (image_target->link_addr + - ALIGN_UP(total_module_size + core_size, 1048576) + - (1 << 20)); ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section)); grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section)); @@ -1500,8 +1504,13 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); if (image_target->id == IMAGE_LOONGSON_ELF) - target_addr = ALIGN_UP (image_target->link_addr - + kernel_size + total_module_size, 32); + { + if (comp == COMPRESSION_NONE) + target_addr = (image_target->link_addr - decompress_size); + else + target_addr = ALIGN_UP (image_target->link_addr + + kernel_size + total_module_size, 32); + } else target_addr = image_target->link_addr; ehdr->e_entry = grub_host_to_target32 (target_addr); From 4959e11109d8305a7a1aefa37cfd6bea60679038 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 17 May 2011 22:48:20 +0200 Subject: [PATCH 196/211] Use mipsel- rather than mips- in directories involving mipsel ports to allow both endiannesses coexist. * configure.ac: proparate target_cpu=mipsel rather than resetting to mips. All conditions adjusted. * tests/util/grub-shell-tester.in: Remove gratuitious target_cpu variable. * util/grub-install.in: Adjust conditions to take renaming into account. * util/grub-mkimage.c (image_targets): Likewise. New target mips-qemu_mips-elf for bigendian mips. --- ChangeLog | 13 +++++++++++ configure.ac | 41 +++++++++++++++++++++------------ tests/util/grub-shell-tester.in | 1 - util/grub-install.in | 6 ++--- util/grub-mkimage.c | 30 ++++++++++++++++++++---- 5 files changed, 68 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d6a02d08..1d4076a5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-05-17 Vladimir Serbinenko + + Use mipsel- rather than mips- in directories involving mipsel ports to + allow both endiannesses coexist. + + * configure.ac: proparate target_cpu=mipsel rather than resetting to + mips. All conditions adjusted. + * tests/util/grub-shell-tester.in: Remove gratuitious target_cpu + variable. + * util/grub-install.in: Adjust conditions to take renaming into account. + * util/grub-mkimage.c (image_targets): Likewise. New target + mips-qemu_mips-elf for bigendian mips. + 2011-05-17 Vladimir Serbinenko Avoid unnecessary copying on MIPS. diff --git a/configure.ac b/configure.ac index 8f854155e..f674a90aa 100644 --- a/configure.ac +++ b/configure.ac @@ -72,7 +72,7 @@ case "$target_cpu" in amd64) target_cpu=x86_64 ;; sparc) target_cpu=sparc64 ;; mipsel|mips64el) - target_cpu=mips; + target_cpu=mipsel; machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1"; ;; mips|mips64) @@ -96,7 +96,8 @@ if test "x$with_platform" = x; then powerpc-*) platform=ieee1275 ;; powerpc64-*) platform=ieee1275 ;; sparc64-*) platform=ieee1275 ;; - mips-*) platform=loongson ;; + mipsel-*) platform=loongson ;; + mips-*) platform=arc ;; ia64-*) platform=efi ;; *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;; esac @@ -126,10 +127,12 @@ case "$target_cpu"-"$platform" in ia64-efi) ;; mips-qemu_mips) ;; mips-qemu-mips) platform=qemu_mips;; - mips-yeeloong) platform=loongson ;; - mips-fuloong) platform=loongson ;; - mips-loongson) ;; mips-arc) ;; + mipsel-qemu_mips) ;; + mipsel-qemu-mips) platform=qemu_mips;; + mipsel-yeeloong) platform=loongson ;; + mipsel-fuloong) platform=loongson ;; + mipsel-loongson) ;; *-emu) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; esac @@ -167,10 +170,14 @@ case "$platform" in arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;; esac case "$target_cpu" in - mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;; + mips |mipsel) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;; sparc64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;; esac -machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" +if test x${target_cpu} = xmipsel ; then + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo mips_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" +else + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" +fi HOST_CPPFLAGS="$HOST_CPPFLAGS $machine_CPPFLAGS" TARGET_CPPFLAGS="$TARGET_CPPFLAGS $machine_CPPFLAGS" @@ -405,7 +412,7 @@ if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm" fi -if test "${target_cpu}-${platform}" = mips-loongson; then +if test "${target_cpu}-${platform}" = mipsel-loongson; then AC_CACHE_CHECK([whether -march=loongson2f works], [grub_cv_cc_march_loongson2f], [ SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -march=loongson2f" @@ -958,12 +965,12 @@ AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot]) AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot]) AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) -AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmips -a x$platform = xloongson]) -AM_CONDITIONAL([COND_mips_qemu_mips], [test x$target_cpu = xmips -a x$platform = xqemu_mips]) +AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson]) +AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips]) AM_CONDITIONAL([COND_mips_arc], [test x$target_cpu = xmips -a x$platform = xarc]) AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) -AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips]) +AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd]) AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) @@ -985,19 +992,23 @@ AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) AM_CONDITIONAL([COND_CYGWIN], [test x$host_os = xcygwin]) # Output files. +cpudir="${target_cpu}" +if test x${cpudir} = xmipsel; then + cpudir=mips; +fi grub_CHECK_LINK_DIR if test x"$link_dir" = xyes ; then - AC_CONFIG_LINKS([include/grub/cpu:include/grub/$target_cpu]) + AC_CONFIG_LINKS([include/grub/cpu:include/grub/$cpudir]) if test "$platform" != emu ; then - AC_CONFIG_LINKS([include/grub/machine:include/grub/$target_cpu/$platform]) + AC_CONFIG_LINKS([include/grub/machine:include/grub/$cpudir/$platform]) fi else mkdir -p include/grub 2>/dev/null rm -rf include/grub/cpu - cp -rp $srcdir/include/grub/$target_cpu include/grub/cpu 2>/dev/null + cp -rp $srcdir/include/grub/$cpudir include/grub/cpu 2>/dev/null if test "$platform" != emu ; then rm -rf include/grub/machine - cp -rp $srcdir/include/grub/$target_cpu/$platform include/grub/machine 2>/dev/null + cp -rp $srcdir/include/grub/$cpudir/$platform include/grub/machine 2>/dev/null fi fi diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in index 02e49d3a4..b839825f1 100644 --- a/tests/util/grub-shell-tester.in +++ b/tests/util/grub-shell-tester.in @@ -27,7 +27,6 @@ builddir=@builddir@ PACKAGE_NAME=@PACKAGE_NAME@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ -target_cpu=@target_cpu@ # Force build directory components PATH=${builddir}:$PATH diff --git a/util/grub-install.in b/util/grub-install.in index ad6ea1037..db3a4db98 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -554,13 +554,13 @@ fi case "${target_cpu}-${platform}" in sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; - mips-loongson) mkimage_target=mipsel-loongson-elf ;; + mipsel-loongson) mkimage_target=mipsel-loongson-elf ;; *) mkimage_target="${target_cpu}-${platform}" ;; esac case "${target_cpu}-${platform}" in i386-efi | x86_64-efi) imgext=efi ;; - mips-loongson | i386-coreboot | i386-multiboot | i386-ieee1275 \ + mipsel-loongson | i386-coreboot | i386-multiboot | i386-ieee1275 \ | powerpc-ieee1275) imgext=elf ;; *) imgext=img ;; esac @@ -569,7 +569,7 @@ esac "$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $modules || exit 1 # Backward-compatibility kludges -if [ "${target_cpu}-${platform}" = "mips-loongson" ]; then +if [ "${target_cpu}-${platform}" = "mipsel-loongson" ]; then cp "${grubdir}/core.${imgext}" "${bootdir}"/grub.elf elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then cp "${grubdir}/core.${imgext}" "${grubdir}/grub" diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 2003a86d2..9fc37df2b 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -274,7 +274,7 @@ struct image_target_desc image_targets[] = .elf_target = EM_X86_64, }, { - .dirname = "mips-loongson", + .dirname = "mipsel-loongson", .names = { "mipsel-yeeloong-flash", NULL }, .voidp_sizeof = 4, .bigendian = 0, @@ -296,7 +296,7 @@ struct image_target_desc image_targets[] = .default_compression = COMPRESSION_NONE }, { - .dirname = "mips-loongson", + .dirname = "mipsel-loongson", .names = { "mipsel-fuloong-flash", NULL }, .voidp_sizeof = 4, .bigendian = 0, @@ -318,7 +318,7 @@ struct image_target_desc image_targets[] = .default_compression = COMPRESSION_NONE }, { - .dirname = "mips-loongson", + .dirname = "mipsel-loongson", .names = { "mipsel-loongson-elf", "mipsel-yeeloong-elf", "mipsel-fuloong-elf", NULL }, .voidp_sizeof = 4, @@ -445,7 +445,7 @@ struct image_target_desc image_targets[] = .default_compression = COMPRESSION_NONE }, { - .dirname = "mips-qemu_mips", + .dirname = "mipsel-qemu_mips", .names = { "mipsel-qemu_mips-elf", NULL }, .voidp_sizeof = 4, .bigendian = 0, @@ -466,6 +466,28 @@ struct image_target_desc image_targets[] = .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, .default_compression = COMPRESSION_NONE }, + { + .dirname = "mips-qemu_mips", + .names = { "mips-qemu_mips-elf", NULL }, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_LOONGSON_ELF, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .prefix = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX, + .prefix_end = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END, + .raw_size = 0, + .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, + .compressed_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression = COMPRESSION_NONE + }, }; #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) From 543a8f6ef929e94a45e293c4aeb3c6fbb9c6963e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 18 May 2011 00:21:49 +0200 Subject: [PATCH 197/211] * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): Fix potential usage of Elf32 instead of Elf64 when compiling on 32-bit architecture. Add endianness macros while on it. --- ChangeLog | 6 ++++++ grub-core/kern/ia64/dl_helper.c | 32 ++++++++++++++++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d4076a5b..59574202a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-05-17 Vladimir Serbinenko + + * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): + Fix potential usage of Elf32 instead of Elf64 when compiling on + 32-bit architecture. Add endianness macros while on it. + 2011-05-17 Vladimir Serbinenko Use mipsel- rather than mips- in directories involving mipsel ports to diff --git a/grub-core/kern/ia64/dl_helper.c b/grub-core/kern/ia64/dl_helper.c index 9503c49ea..91f28026e 100644 --- a/grub-core/kern/ia64/dl_helper.c +++ b/grub-core/kern/ia64/dl_helper.c @@ -27,35 +27,35 @@ void grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got) { - const Elf_Ehdr *e = ehdr; + const Elf64_Ehdr *e = ehdr; grub_size_t cntt = 0, cntg = 0;; - const Elf_Shdr *s; - Elf_Word entsize; + const Elf64_Shdr *s; + Elf64_Word entsize; unsigned i; /* Find a symbol table. */ - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) + for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff)); + i < grub_le_to_cpu16 (e->e_shnum); + i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize))) + if (grub_le_to_cpu32 (s->sh_type) == SHT_SYMTAB) break; - if (i == e->e_shnum) + if (i == grub_le_to_cpu16 (e->e_shnum)) return; entsize = s->sh_entsize; - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_RELA) + for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff)); + i < grub_le_to_cpu16 (e->e_shnum); + i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize))) + if (grub_le_to_cpu32 (s->sh_type) == SHT_RELA) { - Elf_Rela *rel, *max; + Elf64_Rela *rel, *max; - for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; + for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu32 (s->sh_offset)), + max = rel + grub_le_to_cpu32 (s->sh_size) / grub_le_to_cpu16 (s->sh_entsize); rel < max; rel++) - switch (ELF_R_TYPE (rel->r_info)) + switch (ELF64_R_TYPE (grub_le_to_cpu32 (rel->r_info))) { case R_IA64_PCREL21B: cntt++; From 6ad6223e925efc5e0fa1d0d46c8620c09a06ea0b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 18 May 2011 01:38:01 +0200 Subject: [PATCH 198/211] Unify grub-mkrescue (except powerpc) and grrub-mknetdir across platforms * grub-core/Makefile.am (platform_DATA): Add modinfo.sh. * grub-core/modinfo.sh.in: New file. * grub-core/Makefile.core.def (modinfo.sh): New script. * util/grub-mknetdir.in: Use modinfo.sh. * util/grub-mkrescue.in: Likewise. --- ChangeLog | 10 ++++++++++ grub-core/Makefile.am | 1 + grub-core/Makefile.core.def | 6 ++++++ grub-core/modinfo.sh.in | 4 ++++ util/grub-mknetdir.in | 9 +++------ util/grub-mkrescue.in | 7 +++---- 6 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 grub-core/modinfo.sh.in diff --git a/ChangeLog b/ChangeLog index 59574202a..0c3503288 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-05-18 Vladimir Serbinenko + + Unify grub-mkrescue (except powerpc) and grrub-mknetdir across platforms + + * grub-core/Makefile.am (platform_DATA): Add modinfo.sh. + * grub-core/modinfo.sh.in: New file. + * grub-core/Makefile.core.def (modinfo.sh): New script. + * util/grub-mknetdir.in: Use modinfo.sh. + * util/grub-mkrescue.in: Likewise. + 2011-05-17 Vladimir Serbinenko * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 88858c8ab..98e275f7e 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -329,6 +329,7 @@ CLEANFILES += config.log syminfo.lst moddep.lst $(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@ platform_DATA += $(MOD_FILES) +platform_DATA += modinfo.sh CLEANFILES += $(MOD_FILES) if COND_ENABLE_EFIEMU diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index c717167cb..8afb98b73 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -12,6 +12,12 @@ script = { common = genmod.sh.in; }; +script = { + installdir = noinst; + name = modinfo.sh; + common = modinfo.sh.in; +}; + kernel = { name = kernel; diff --git a/grub-core/modinfo.sh.in b/grub-core/modinfo.sh.in new file mode 100644 index 000000000..ff31ca816 --- /dev/null +++ b/grub-core/modinfo.sh.in @@ -0,0 +1,4 @@ +#!/bin/sh + +grub_modinfo_target_cpu=@target_cpu@ +grub_modinfo_platform=@platform@ diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in index b353e98b9..61a7ec3ad 100644 --- a/util/grub-mknetdir.in +++ b/util/grub-mknetdir.in @@ -27,12 +27,8 @@ libdir=@libdir@ PACKAGE_NAME=@PACKAGE_NAME@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ -target_cpu=@target_cpu@ -platform=@platform@ host_os=@host_os@ -pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` localedir=@datadir@/locale -native_platform=@platform@ pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst" self=`basename $0` @@ -64,7 +60,7 @@ Install GRUB on your drive. --subdir=DIR relative subdirectory on network server --grub-mkimage=FILE use FILE as grub-mkimage -$self copies GRUB images into net_directory/subdir/${target_cpu}-${platform} +$self copies GRUB images into net_directory/subdir/target_cpu-platform Report bugs to . EOF @@ -222,7 +218,8 @@ if [ "${override_dir}" = "" ] ; then process_input_dir ${pc_dir} i386-pc fi else - process_input_dir ${override_dir} ${target_cpu}-${native_platform} + source "${override_dir}"/modinfo.sh + process_input_dir "${override_dir}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} fi diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index f7f751708..2b6c9d391 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -27,8 +27,6 @@ libdir=@libdir@ PACKAGE_NAME=@PACKAGE_NAME@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ -target_cpu=@target_cpu@ -native_platform=@platform@ pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst" self=`basename $0` @@ -231,14 +229,15 @@ if [ "${override_dir}" = "" ] ; then process_input_dir ${efi64_dir} x86_64-efi fi else - process_input_dir ${override_dir} ${target_cpu}-${native_platform} + source "${override_dir}"/modinfo.sh + process_input_dir "${override_dir}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} multiboot_dir= pc_dir= efi32_dir= efi64_dir= coreboot_dir= qemu_dir= - case "${target_cpu}-${native_platform}" in + case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in i386-multiboot) multiboot_dir=${override_dir} ;; i386-coreboot) coreboot_dir=${override_dir} ;; i386-qemu) qemu_dir=${override_dir} ;; From cf02731e4837930b21bcb30346ae696d4c9a90d2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 18 May 2011 12:39:22 +0200 Subject: [PATCH 199/211] * grub-core/Makefile.core.def (ieee1275_fb): Use enable=powerpc_ieee1275 for cleanness. --- ChangeLog | 5 +++++ grub-core/Makefile.core.def | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 48b7bc171..eb86c47ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-18 Vladimir Serbinenko + + * grub-core/Makefile.core.def (ieee1275_fb): Use enable=powerpc_ieee1275 + for cleanness. + 2011-05-18 Vladimir Serbinenko FreeDOS direct loading support. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 76539e8d2..f10b63238 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1548,7 +1548,7 @@ module = { module = { name = ieee1275_fb; ieee1275 = video/ieee1275.c; - enable = powerpc; + enable = powerpc_ieee1275; }; module = { From 69b11a560c9b3f9f8f42cb3e6290a0db82b3df30 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 18 May 2011 12:41:22 +0200 Subject: [PATCH 200/211] add missing file --- include/grub/fat.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 include/grub/fat.h diff --git a/include/grub/fat.h b/include/grub/fat.h new file mode 100644 index 000000000..7d8e51ad5 --- /dev/null +++ b/include/grub/fat.h @@ -0,0 +1,70 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_FAT_H +#define GRUB_FAT_H 1 + +#include + +struct grub_fat_bpb +{ + grub_uint8_t jmp_boot[3]; + grub_uint8_t oem_name[8]; + grub_uint16_t bytes_per_sector; + grub_uint8_t sectors_per_cluster; + grub_uint16_t num_reserved_sectors; + grub_uint8_t num_fats; + grub_uint16_t num_root_entries; + grub_uint16_t num_total_sectors_16; + grub_uint8_t media; + grub_uint16_t sectors_per_fat_16; + grub_uint16_t sectors_per_track; + grub_uint16_t num_heads; + grub_uint32_t num_hidden_sectors; + grub_uint32_t num_total_sectors_32; + union + { + struct + { + grub_uint8_t num_ph_drive; + grub_uint8_t reserved; + grub_uint8_t boot_sig; + grub_uint32_t num_serial; + grub_uint8_t label[11]; + grub_uint8_t fstype[8]; + } __attribute__ ((packed)) fat12_or_fat16; + struct + { + grub_uint32_t sectors_per_fat_32; + grub_uint16_t extended_flags; + grub_uint16_t fs_version; + grub_uint32_t root_cluster; + grub_uint16_t fs_info; + grub_uint16_t backup_boot_sector; + grub_uint8_t reserved[12]; + grub_uint8_t num_ph_drive; + grub_uint8_t reserved1; + grub_uint8_t boot_sig; + grub_uint32_t num_serial; + grub_uint8_t label[11]; + grub_uint8_t fstype[8]; + } __attribute__ ((packed)) fat32; + } __attribute__ ((packed)) version_specific; +} __attribute__ ((packed)); + +#endif From 26618ff0db4b9454685ebd93414aef4eae868fa4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 18 May 2011 12:51:05 +0200 Subject: [PATCH 201/211] Patch BPB in ntldr and chainloader --bpb. * grub-core/fs/fat.c: Include grub/fat.h. (grub_fat_bpb): Moved to ... * include/grub/fat.h (grub_fat_bpb): ... here. New file. * grub-core/loader/i386/pc/chainloader.c: Include grub/fat.h and grub/ntfs.h. * include/grub/i386/pc/chainloader.h (grub_chainloader_flags_t): Moved from here... * grub-core/loader/i386/pc/chainloader.c (grub_chainloader_flags_t): ... here. * grub-core/loader/i386/pc/chainloader.c (grub_chainloader_patch_bpb): New function. (grub_chainloader_cmd): Patch BPB if --bpb is given. (GRUB_MOD_INIT): Show --bpb. * grub-core/loader/i386/pc/ntldr.c (grub_cmd_ntldr): Patch BPB. * grub-core/normal/main.c (features): New variable. (GRUB_MOD_INIT): Set feature_* variables. * include/grub/i386/pc/chainloader.h (grub_chainloader_patch_bpb): New proto. * include/grub/ntfs.h (grub_ntfs_bpb): New field bios_drive. --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9ea22d970..e80ff7870 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2011-05-18 Vladimir Serbinenko + Patch BPB in ntldr and chainloader --bpb. + * grub-core/fs/fat.c: Include grub/fat.h. (grub_fat_bpb): Moved to ... * include/grub/fat.h (grub_fat_bpb): ... here. New file. From 5626056ffb35ed0320fed4bceac9768ebc8c31d2 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 18 May 2011 12:53:07 +0100 Subject: [PATCH 202/211] * grub-core/genmod.sh.in: Use 'set -e' rather than '#! /bin/sh -e', to avoid accidents when debugging with 'sh -x'. * grub-core/gensyminfo.sh.in: Likewise. * tests/example_scripted_test.in: Likewise. * tests/grub_cmd_regexp.in: Likewise. * tests/grub_script_blanklines.in: Likewise. * tests/grub_script_dollar.in: Likewise. * tests/grub_script_expansion.in: Likewise. * tests/grub_script_final_semicolon.in: Likewise. * tests/partmap_test.in: Likewise. * tests/util/grub-shell-tester.in: Likewise. * tests/util/grub-shell.in: Likewise. --- ChangeLog | 15 +++++++++++++++ grub-core/genmod.sh.in | 5 +++-- grub-core/gensyminfo.sh.in | 5 +++-- tests/example_scripted_test.in | 3 ++- tests/grub_cmd_regexp.in | 3 ++- tests/grub_script_blanklines.in | 3 ++- tests/grub_script_dollar.in | 3 ++- tests/grub_script_expansion.in | 3 ++- tests/grub_script_final_semicolon.in | 3 ++- tests/partmap_test.in | 5 +++-- tests/util/grub-shell-tester.in | 3 ++- tests/util/grub-shell.in | 3 ++- 12 files changed, 40 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ed12abbe..bac09e101 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2011-05-18 Colin Watson + + * grub-core/genmod.sh.in: Use 'set -e' rather than '#! /bin/sh -e', + to avoid accidents when debugging with 'sh -x'. + * grub-core/gensyminfo.sh.in: Likewise. + * tests/example_scripted_test.in: Likewise. + * tests/grub_cmd_regexp.in: Likewise. + * tests/grub_script_blanklines.in: Likewise. + * tests/grub_script_dollar.in: Likewise. + * tests/grub_script_expansion.in: Likewise. + * tests/grub_script_final_semicolon.in: Likewise. + * tests/partmap_test.in: Likewise. + * tests/util/grub-shell-tester.in: Likewise. + * tests/util/grub-shell.in: Likewise. + 2011-05-18 Colin Watson Move gfxmenu color handling to video, so that gfxterm can use it diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in index 023cd1062..4cab8e50e 100644 --- a/grub-core/genmod.sh.in +++ b/grub-core/genmod.sh.in @@ -1,5 +1,6 @@ -#! /bin/sh -e -# +#! /bin/sh +set -e + # Copyright (C) 2010 Free Software Foundation, Inc. # # This gensymlist.sh is free software; the author diff --git a/grub-core/gensyminfo.sh.in b/grub-core/gensyminfo.sh.in index 4f5184913..d383f2640 100644 --- a/grub-core/gensyminfo.sh.in +++ b/grub-core/gensyminfo.sh.in @@ -1,5 +1,6 @@ -#! /bin/sh -e -# +#! /bin/sh +set -e + # Copyright (C) 2010 Free Software Foundation, Inc. # # This gensymlist.sh is free software; the author diff --git a/tests/example_scripted_test.in b/tests/example_scripted_test.in index 9ac0424c0..09633e893 100644 --- a/tests/example_scripted_test.in +++ b/tests/example_scripted_test.in @@ -1,3 +1,4 @@ -#!/bin/sh -e +#!/bin/sh +set -e true diff --git a/tests/grub_cmd_regexp.in b/tests/grub_cmd_regexp.in index 43b479fec..e7e625701 100644 --- a/tests/grub_cmd_regexp.in +++ b/tests/grub_cmd_regexp.in @@ -1,4 +1,5 @@ -#! /bin/bash -e +#! /bin/bash +set -e # Run GRUB script in a Qemu instance # Copyright (C) 2010 Free Software Foundation, Inc. diff --git a/tests/grub_script_blanklines.in b/tests/grub_script_blanklines.in index 71b869bd3..89ed763d3 100644 --- a/tests/grub_script_blanklines.in +++ b/tests/grub_script_blanklines.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e @builddir@/grub-script-check < Date: Wed, 18 May 2011 12:57:59 +0100 Subject: [PATCH 203/211] * util/grub-mkrescue.in: Use portable `.' rather than non-portable `source'. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bac09e101..7b44c32fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-18 Colin Watson + + * util/grub-mkrescue.in: Use portable `.' rather than non-portable + `source'. + 2011-05-18 Colin Watson * grub-core/genmod.sh.in: Use 'set -e' rather than '#! /bin/sh -e', diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 2b6c9d391..8367c4dd4 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -229,7 +229,7 @@ if [ "${override_dir}" = "" ] ; then process_input_dir ${efi64_dir} x86_64-efi fi else - source "${override_dir}"/modinfo.sh + . "${override_dir}"/modinfo.sh process_input_dir "${override_dir}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} multiboot_dir= pc_dir= From bf947d36e3408fd4f5c74b7751663924500a53ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 18 May 2011 15:35:19 +0200 Subject: [PATCH 204/211] Use full 64-bit division. * grub-core/kern/misc.c (grub_divmod64_full): Renamed to ... (grub_divmod64): ... this. * include/grub/misc.h (grub_divmod64): Removed. All users switch to full version. --- ChangeLog | 9 +++++++++ grub-core/commands/ls.c | 5 +++-- grub-core/disk/i386/pc/biosdisk.c | 2 +- grub-core/disk/lvm.c | 4 ++-- grub-core/disk/raid.c | 4 ++-- grub-core/disk/scsi.c | 2 +- grub-core/fs/affs.c | 2 +- grub-core/fs/btrfs.c | 16 ++++++++-------- grub-core/fs/i386/pc/pxe.c | 3 ++- grub-core/fs/minix.c | 4 ++-- grub-core/fs/nilfs2.c | 14 ++++++++------ grub-core/fs/ntfs.c | 2 +- grub-core/io/bufio.c | 2 +- grub-core/kern/misc.c | 4 ++-- include/grub/misc.h | 17 +++-------------- 15 files changed, 46 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b44c32fc..cd49e296e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-05-18 Vladimir Serbinenko + + Use full 64-bit division. + + * grub-core/kern/misc.c (grub_divmod64_full): Renamed to ... + (grub_divmod64): ... this. + * include/grub/misc.h (grub_divmod64): Removed. All users switch to full + version. + 2011-05-18 Colin Watson * util/grub-mkrescue.in: Use portable `.' rather than non-portable diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c index 5fc648a9b..4c4051a22 100644 --- a/grub-core/commands/ls.c +++ b/grub-core/commands/ls.c @@ -134,11 +134,12 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) if (units) { - grub_uint32_t whole, fraction; + grub_uint64_t whole, fraction; whole = grub_divmod64 (fsize, 100, &fraction); grub_snprintf (buf, sizeof (buf), - "%u.%02u%c", whole, fraction, + "%" PRIuGRUB_UINT64_T + ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction, grub_human_sizes[units]); grub_printf ("%-12s", buf); } diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 1d47dc727..3baf20717 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -506,7 +506,7 @@ static grub_size_t get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors) { grub_size_t size; - grub_uint32_t offset; + grub_uint64_t offset; /* OFFSET = SECTOR % SECTORS */ grub_divmod64 (sector, sectors, &offset); diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 206e3e220..563b49b49 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -247,9 +247,9 @@ read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector, /* This is a striped segment. We have to find the right PV similar to RAID0. */ struct grub_lvm_node *stripe = seg->nodes; - grub_uint32_t a, b; + grub_uint64_t a, b; grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ - unsigned int stripenr; + grub_uint64_t stripenr; offset = sector - ((grub_uint64_t) seg->start_extent * (grub_uint64_t) vg->extent_size); diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 946e6d2c2..c6be3efde 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -245,7 +245,7 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, case 10: { grub_disk_addr_t read_sector, far_ofs; - grub_uint32_t disknr, b, near, far, ofs; + grub_uint64_t disknr, b, near, far, ofs; read_sector = grub_divmod64 (sector, array->chunk_size, &b); far = ofs = near = 1; @@ -351,7 +351,7 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, case 6: { grub_disk_addr_t read_sector; - grub_uint32_t b, p, n, disknr, e; + grub_uint64_t b, p, n, disknr, e; /* n = 1 for level 4 and 5, 2 for level 6. */ n = array->level / 3; diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index 25f0e3aea..d683cbfe7 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -512,7 +512,7 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "unsupported SCSI block size"); - grub_uint32_t sector_mod = 0; + grub_uint64_t sector_mod = 0; sector = grub_divmod64 (sector, spb, §or_mod); if (! (sector_mod == 0 && size % spb == 0)) diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 7c2099410..e17540e2f 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -125,7 +125,7 @@ grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) int block = node->block; struct grub_affs_file file; struct grub_affs_data *data = node->data; - grub_uint32_t mod; + grub_uint64_t mod; /* Find the block that points to the fileblock we are looking up by following the chain until the right table is reached. */ diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 59e91b552..533529e3f 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -649,7 +649,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, chunk_found: { - grub_uint32_t stripen; + grub_uint64_t stripen; grub_uint64_t stripe_offset; grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset); unsigned redundancy = 1; @@ -679,10 +679,10 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, { grub_uint64_t stripe_length; grub_dprintf ("btrfs", "single\n"); - stripe_length = grub_divmod64_full (grub_le_to_cpu64 (chunk->size), - grub_le_to_cpu16 (chunk->nstripes), - NULL); - stripen = grub_divmod64_full (off, stripe_length, &stripe_offset); + stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), + grub_le_to_cpu16 (chunk->nstripes), + NULL); + stripen = grub_divmod64 (off, stripe_length, &stripe_offset); csize = (stripen + 1) * stripe_length - off; break; } @@ -699,7 +699,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, case GRUB_BTRFS_CHUNK_TYPE_RAID0: { grub_uint64_t middle, high; - grub_uint32_t low; + grub_uint64_t low; grub_dprintf ("btrfs", "RAID0\n"); middle = grub_divmod64 (off, grub_le_to_cpu64 (chunk->stripe_length), @@ -715,7 +715,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, case GRUB_BTRFS_CHUNK_TYPE_RAID10: { grub_uint64_t middle, high; - grub_uint32_t low; + grub_uint64_t low; middle = grub_divmod64 (off, grub_le_to_cpu64 (chunk->stripe_length), &low); @@ -760,7 +760,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T "+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %" - PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT32_T + PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT64_T " maps to 0x%" PRIxGRUB_UINT64_T "\n", grub_le_to_cpu64 (key->offset), grub_le_to_cpu64 (chunk->size), diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index 4304881fa..7d86b78bf 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -306,7 +306,8 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len) struct grub_pxenv_tftp_read c; struct grub_pxe_data *data; struct grub_pxe_disk_data *disk_data = file->device->disk->data; - grub_uint32_t pn, r; + grub_uint32_t pn; + grub_uint64_t r; data = file->data; diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 91659b0f6..64a64cca0 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -229,7 +229,7 @@ grub_minix_read_file (struct grub_minix_data *data, grub_disk_addr_t i; grub_disk_addr_t blockcnt; grub_uint64_t posblock; - grub_uint32_t blockoff; + grub_uint64_t blockoff; /* Adjust len so it we can't read past the end of the file. */ if (len + pos > GRUB_MINIX_INODE_SIZE (data)) @@ -242,7 +242,7 @@ grub_minix_read_file (struct grub_minix_data *data, for (i = posblock; i < blockcnt; i++) { grub_disk_addr_t blknr; - grub_uint32_t blockend = data->block_size; + grub_uint64_t blockend = data->block_size; grub_off_t skipfirst = 0; blknr = grub_minix_get_file_block (data, i); diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index 4c8d7633c..44fb213bd 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -303,7 +303,7 @@ grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data) static inline grub_uint64_t grub_nilfs2_palloc_group (struct grub_nilfs2_data *data, - grub_uint64_t nr, grub_uint32_t * offset) + grub_uint64_t nr, grub_uint64_t * offset) { return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data), offset); @@ -368,13 +368,15 @@ grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data, grub_uint64_t nr, unsigned long entry_size) { unsigned long group; - grub_uint32_t group_offset; + grub_uint64_t group_offset; group = grub_nilfs2_palloc_group (data, nr, &group_offset); return grub_nilfs2_palloc_bitmap_block_offset (data, group, entry_size) + 1 + - group_offset / grub_nilfs2_entries_per_block (data, entry_size); + grub_divmod64 (group_offset, grub_nilfs2_entries_per_block (data, + entry_size), + NULL); } @@ -577,7 +579,7 @@ grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key) struct grub_nilfs2_dat_entry entry; grub_disk_t disk = data->disk; grub_uint64_t pptr; - grub_uint32_t blockno, offset; + grub_uint64_t blockno, offset; unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); blockno = grub_nilfs2_palloc_entry_offset (data, key, @@ -641,7 +643,7 @@ grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data, struct grub_nilfs2_checkpoint *cpp) { grub_uint64_t blockno; - grub_uint32_t offset; + grub_uint64_t offset; grub_uint64_t pptr; grub_disk_t disk = data->disk; unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); @@ -679,7 +681,7 @@ grub_nilfs2_read_inode (struct grub_nilfs2_data *data, grub_uint64_t ino, struct grub_nilfs2_inode *inodep) { grub_uint64_t blockno; - unsigned int offset; + grub_uint64_t offset; grub_uint64_t pptr; grub_disk_t disk = data->disk; unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 1a8d3f17f..5d128bcc0 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -431,7 +431,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, if (at->flags & AF_GPOS) { grub_disk_addr_t st0, st1; - grub_uint32_t m; + grub_uint64_t m; grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m); diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c index 3b456c1d2..adb38af56 100644 --- a/grub-core/io/bufio.c +++ b/grub-core/io/bufio.c @@ -106,7 +106,7 @@ grub_bufio_read (grub_file_t file, char *buf, grub_size_t len) { grub_size_t res = len; grub_bufio_t bufio = file->data; - grub_uint32_t pos; + grub_uint64_t pos; if ((file->offset >= bufio->file->offset) && (file->offset < bufio->file->offset + bufio->buffer_len)) diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 1b4cdec66..a3dfabf82 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -597,7 +597,7 @@ grub_reverse (char *str) /* Divide N by D, return the quotient, and store the remainder in *R. */ grub_uint64_t -grub_divmod64_full (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r) +grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r) { /* This algorithm is typically implemented by hardware. The idea is to get the highest bit in N, 64 times, by keeping @@ -666,7 +666,7 @@ grub_lltoa (char *str, int c, unsigned long long n) /* BASE == 10 */ do { - unsigned m; + grub_uint64_t m; n = grub_divmod64 (n, 10, &m); *p++ = m + '0'; diff --git a/include/grub/misc.h b/include/grub/misc.h index 80588be33..da4bd4a7e 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -287,20 +287,9 @@ char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...) char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) __attribute__ ((warn_unused_result)); void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); -grub_uint64_t EXPORT_FUNC(grub_divmod64_full) (grub_uint64_t n, - grub_uint64_t d, - grub_uint64_t *r); -static inline grub_uint64_t grub_divmod64 (grub_uint64_t n, - grub_uint32_t d, - grub_uint32_t *r) -{ - grub_uint64_t ret, rr; - - ret = grub_divmod64_full (n, d, &rr); - if (r) - *r = rr; - return ret; -} +grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, + grub_uint64_t d, + grub_uint64_t *r); #if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL) void EXPORT_FUNC(__enable_execute_stack) (void *addr); From e775d8edfe32cadb0294241a89cabbb00e338e39 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 18 May 2011 15:37:18 +0200 Subject: [PATCH 205/211] * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Downgrade a printf into dprintf. --- ChangeLog | 5 +++++ grub-core/bus/usb/usbhub.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd49e296e..1a3731242 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-18 Vladimir Serbinenko + + * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Downgrade a printf + into dprintf. + 2011-05-18 Vladimir Serbinenko Use full 64-bit division. diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c index fff94a3fc..b59f2f51d 100644 --- a/grub-core/bus/usb/usbhub.c +++ b/grub-core/bus/usb/usbhub.c @@ -352,8 +352,8 @@ poll_nonroot_hub (grub_usb_device_t dev) GRUB_USB_REQ_GET_STATUS, 0, i, sizeof (status), (char *) &status); - grub_printf ("dev = %p, i = %d, status = %08x\n", - dev, i, status); + grub_dprintf ("usb", "dev = %p, i = %d, status = %08x\n", + dev, i, status); if (err) continue; From 8b63a142977cf48d33fd5486a8afeac9de78aca4 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 18 May 2011 16:10:52 +0100 Subject: [PATCH 206/211] * .bzrignore: Add grub-core/modinfo.sh and a number of test files. --- .bzrignore | 26 ++++++++++++++++++++++++++ ChangeLog | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/.bzrignore b/.bzrignore index 668d060ca..69aedc290 100644 --- a/.bzrignore +++ b/.bzrignore @@ -26,11 +26,16 @@ docs/*.info docs/stamp-vti docs/version.texi *.elf +example_grub_script_test +example_scripted_test +example_unit_test *.exec genkernsyms.sh gensymlist.sh gentrigtables grub-bin2h +grub_cmd_echo +grub_cmd_regexp grub-editenv grub-emu grub_emu_init.c @@ -48,9 +53,28 @@ grub-probe grub_probe_init.c grub_probe_init.h grub-reboot +grub_script_blanklines +grub_script_blockarg +grub_script_break grub-script-check grub_script_check_init.c grub_script_check_init.h +grub_script_comments +grub_script_continue +grub_script_dollar +grub_script_echo1 +grub_script_echo_keywords +grub_script_expansion +grub_script_final_semicolon +grub_script_for1 +grub_script_functions +grub_script_if +grub_script_not +grub_script_return +grub_script_setparams +grub_script_shift +grub_script_vars1 +grub_script_while1 grub_script.tab.c grub_script.tab.h grub_script.yy.c @@ -74,6 +98,7 @@ Makefile *.mod mod-*.c missing +partmap_test *.pf2 *.pp po/*.mo @@ -108,6 +133,7 @@ grub-core/Makefile.gcry.def grub-core/contrib grub-core/genmod.sh grub-core/gensyminfo.sh +grub-core/modinfo.sh grub-core/*.module grub-core/*.pp util/bash-completion.d/grub diff --git a/ChangeLog b/ChangeLog index 1a3731242..3980ef7b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-05-18 Colin Watson + + * .bzrignore: Add grub-core/modinfo.sh and a number of test files. + 2011-05-18 Vladimir Serbinenko * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Downgrade a printf From 63e3eea967a3b7148adbf97195023fb6460a9989 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 18 May 2011 17:31:50 +0100 Subject: [PATCH 207/211] * Makefile.util.def (grub-ofpathname): Install manual page. --- ChangeLog | 4 ++++ Makefile.util.def | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2708949d1..c8e754685 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-05-18 Colin Watson + + * Makefile.util.def (grub-ofpathname): Install manual page. + 2011-05-18 Colin Watson * grub-core/fs/squash4.c: Add missing GRUB_MOD_LICENSE. diff --git a/Makefile.util.def b/Makefile.util.def index 380c939b9..829b16fac 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -288,6 +288,7 @@ program = { program = { name = grub-ofpathname; installdir = sbin; + mansection = 8; ieee1275 = util/ieee1275/grub-ofpathname.c; ieee1275 = util/ieee1275/ofpath.c; From 9a79fcf2c9b56bc85f9d104f947125aa73099c31 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 May 2011 12:13:18 +0200 Subject: [PATCH 208/211] * grub-core/Makefile.core.def (lsacpi): Fix ia64 mismerge. (lsefisystab): Likewise. (lssal): Likewise. (lsefimmap): Likewise. (hdparm): Enable on qemu-mips. (setjmp): Add ia64 nodist. (serial): Simplify tags. --- ChangeLog | 10 ++++++++++ grub-core/Makefile.core.def | 13 +++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index c8e754685..1a68f911c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-05-19 Vladimir Serbinenko + + * grub-core/Makefile.core.def (lsacpi): Fix ia64 mismerge. + (lsefisystab): Likewise. + (lssal): Likewise. + (lsefimmap): Likewise. + (hdparm): Enable on qemu-mips. + (setjmp): Add ia64 nodist. + (serial): Simplify tags. + 2011-05-18 Colin Watson * Makefile.util.def (grub-ofpathname): Install manual page. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 6f0dce6ff..3fdf395b4 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -505,7 +505,7 @@ module = { common = commands/lsacpi.c; - enable = x86_efi; + enable = efi; enable = i386_pc; enable = i386_coreboot; enable = i386_multiboot; @@ -516,7 +516,7 @@ module = { common = commands/efi/lsefisystab.c; - enable = x86_efi; + enable = efi; }; module = { @@ -524,7 +524,7 @@ module = { common = commands/efi/lssal.c; - enable = x86_efi; + enable = efi; }; module = { @@ -532,7 +532,7 @@ module = { common = commands/efi/lsefimmap.c; - enable = x86_efi; + enable = efi; }; module = { @@ -632,6 +632,7 @@ module = { common = commands/hdparm.c; common = lib/hexdump.c; enable = pci; + enable = mips_qemu_mips; }; module = { @@ -1197,6 +1198,7 @@ module = { extra_dist = lib/x86_64/setjmp.S; extra_dist = lib/sparc64/setjmp.S; extra_dist = lib/powerpc/setjmp.S; + extra_dist = lib/ia64/setjmp.S; }; module = { @@ -1421,8 +1423,7 @@ module = { x86 = term/ns8250.c; enable = emu; - enable = i386; - enable = x86_64_efi; + enable = x86; emu_condition = COND_GRUB_EMU_USB; }; From f35fa3a664474529be91252380eab589838add6d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 20 May 2011 11:21:36 +0100 Subject: [PATCH 209/211] * util/grub-mkconfig.in: Export GRUB_CMDLINE_LINUX_XEN_REPLACE and GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT. Reported by: Pawel Tecza. --- ChangeLog | 6 ++++++ util/grub-mkconfig.in | 2 ++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1a68f911c..c94b7482d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-05-20 Colin Watson + + * util/grub-mkconfig.in: Export GRUB_CMDLINE_LINUX_XEN_REPLACE and + GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT. + Reported by: Pawel Tecza. + 2011-05-19 Vladimir Serbinenko * grub-core/Makefile.core.def (lsacpi): Fix ia64 mismerge. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index afc66f886..4d627c057 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -239,6 +239,8 @@ export GRUB_DEFAULT \ GRUB_CMDLINE_LINUX_DEFAULT \ GRUB_CMDLINE_XEN \ GRUB_CMDLINE_XEN_DEFAULT \ + GRUB_CMDLINE_LINUX_XEN_REPLACE \ + GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT \ GRUB_CMDLINE_NETBSD \ GRUB_CMDLINE_NETBSD_DEFAULT \ GRUB_TERMINAL_INPUT \ From f767c929f2c430bb574a358e0ba8375d49c6ee64 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 21 May 2011 07:03:55 +0200 Subject: [PATCH 210/211] Don't stat devices unless we have to. * grub-core/kern/emu/getroot.c (grub_find_device): Recognize dir == /dev/mapper. (grub_guess_root_device): Use already known os_dev if possible. * grub-core/kern/emu/hostdisk.c (convert_system_partition_to_system_disk): Scan only in /dev/mapper if device is known to be a dm one. Also-By: Colin Watson --- ChangeLog | 12 ++++++++++++ grub-core/kern/emu/getroot.c | 33 ++++++++++++++++++++------------- grub-core/kern/emu/hostdisk.c | 3 ++- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index c94b7482d..a01d57576 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-05-21 Colin Watson +2011-05-21 Vladimir Serbinenko + + Don't stat devices unless we have to. + + * grub-core/kern/emu/getroot.c (grub_find_device): Recognize + dir == /dev/mapper. + (grub_guess_root_device): Use already known os_dev if possible. + * grub-core/kern/emu/hostdisk.c + (convert_system_partition_to_system_disk): Scan only in /dev/mapper + if device is known to be a dm one. + 2011-05-20 Colin Watson * util/grub-mkconfig.in: Export GRUB_CMDLINE_LINUX_XEN_REPLACE and diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index b1b4f188c..6e49cc31b 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -358,7 +358,7 @@ grub_find_device (const char *dir, dev_t dev) if (S_ISLNK (st.st_mode)) { #ifdef __linux__ - if (strcmp (dir, "mapper") == 0) { + if (strcmp (dir, "mapper") == 0 || strcmp (dir, "/dev/mapper") == 0) { /* Follow symbolic links under /dev/mapper/; the canonical name may be something like /dev/dm-0, but the names under /dev/mapper/ are more human-readable and so we prefer them if @@ -609,20 +609,27 @@ grub_guess_root_device (const char *dir) if (os_dev) { - if (stat (os_dev, &st) >= 0) - dev = st.st_rdev; - else - grub_util_error ("cannot stat `%s'", os_dev); - free (os_dev); - } - else - { - if (stat (dir, &st) >= 0) - dev = st.st_dev; - else - grub_util_error ("cannot stat `%s'", dir); + char *tmp = os_dev; + os_dev = canonicalize_file_name (os_dev); + free (tmp); } + if (os_dev) + { + if (strncmp (os_dev, "/dev/dm-", sizeof ("/dev/dm-") - 1) != 0) + return os_dev; + if (stat (os_dev, &st) < 0) + grub_util_error ("cannot stat `%s'", os_dev); + free (os_dev); + dev = st.st_rdev; + return grub_find_device ("/dev/mapper", dev); + } + + if (stat (dir, &st) < 0) + grub_util_error ("cannot stat `%s'", dir); + + dev = st.st_dev; + #ifdef __CYGWIN__ /* Cygwin specific function. */ os_dev = grub_find_device (dir, dev); diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index d3db7e6be..d633059c3 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1408,7 +1408,8 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) if (tree) dm_tree_free (tree); free (path); - char *ret = grub_find_device (NULL, (major << 8) | minor); + char *ret = grub_find_device ("/dev/mapper", + (major << 8) | minor); return ret; } From 245f4aba489e3a21129253c28dc138571738a5e4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 May 2011 07:05:46 +0200 Subject: [PATCH 211/211] * grub-core/disk/arc/arcdisk.c (reopen): Close old handle before opening new one. --- ChangeLog | 5 +++++ grub-core/disk/arc/arcdisk.c | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index a01d57576..198750f6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-21 Vladimir Serbinenko + + * grub-core/disk/arc/arcdisk.c (reopen): Close old handle before + opening new one. + 2011-05-21 Colin Watson 2011-05-21 Vladimir Serbinenko diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c index e8416634a..7dff30931 100644 --- a/grub-core/disk/arc/arcdisk.c +++ b/grub-core/disk/arc/arcdisk.c @@ -1,7 +1,7 @@ /* ofdisk.c - Open Firmware disk access. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2004,2006,2007,2008,2009,2011 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 @@ -105,11 +105,6 @@ reopen (const char *name) grub_dprintf ("arcdisk", "using already opened %s\n", name); return GRUB_ERR_NONE; } - if (GRUB_ARC_FIRMWARE_VECTOR->open (name, 0, &handle)) - { - grub_dprintf ("arcdisk", "couldn't open %s\n", name); - return grub_error (GRUB_ERR_IO, "couldn't open %s", name); - } if (last_path) { GRUB_ARC_FIRMWARE_VECTOR->close (last_handle); @@ -117,6 +112,11 @@ reopen (const char *name) last_path = NULL; last_handle = 0; } + if (GRUB_ARC_FIRMWARE_VECTOR->open (name, 0, &handle)) + { + grub_dprintf ("arcdisk", "couldn't open %s\n", name); + return grub_error (GRUB_ERR_IO, "couldn't open %s", name); + } last_path = grub_strdup (name); if (!last_path) return grub_errno;